Учебное пособие. Курс: «Администрирование СУБД Tantor»


Оглавление

Авторские права        5

Раздел 1. Установка БД        6

Установка и управление        6

Установка СУБД Tantor        6

Управление экземпляром кластера баз данных        15

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

Терминальный клиент psql        25

Графическая утилита pgAdmin        34

Раздел 2. Архитектура        42

Общие сведения        42

Клиент-сервер        42

Транзакции        50

Фоновые процессы        53

Структуры памяти        56

Буферный кэш        56

WAL        61

Контрольная точка        66

Многоверсионность        69

Кортежи        69

Механизм        72

Снимок данных        75

Уровни изоляции        77

Фиксация и откат транзакции        79

Блокировки объектов        83

Блокировка строк        85

Регламентные работы        88

Задачи очистки        89

Автоочистка        93

Заморозка        99

Выполнение запросов        103

Общие сведения        103

Парсинг        105

Планирование        107

Выполнение        109

Чтение плана запроса        111

Оценка        117

Статистика        120

Расширяемость        124

Механизм использования        124

Обновление        130

FDW        132

Раздел 3. Конфигурирование        134

Конфигурирование        134

Обзор        134

Изменение параметров конфигурации        138

Уровни установки параметров        142

Категории параметров        144

Параметры специфичные для СУБД Tantor        147

Предустановленные параметры        155

Конфигурационные параметры        161

Раздел 4. Базы данных        163

Логическая структура кластера        163

Кластер базы данных        163

Базы данных        166

Схемы        171

Системный каталог        178

Физическая структура кластера        183

Физическая реализация        183

Табличные пространства        187

Слои объектов        194

Размер объектов        197

Перенос объектов        198

Расширения        200

Раздел 5. Журналирование        208

Журнал событий        208

Конфигурирование        208

Форматы        213

Процесс logging_collector        214

Раздел 6. Безопасность        215

Ролевая модель безопасности        215

Роли        215

Привилегии        220

Политика защиты строк        224

Подключение и аутентификация        227

Задачи авторизации        227

Конфигурирование        229

pg_hba        230

pg_ident        234

Раздел 7. Резервное копирование        236

Физическое копирование        236

Виды резервных копий        236

Архитектура резервирования и восстановления        239

Виды резервирования        243

Журнал предзаписи        248

Резервирование        252

Логическое копирование        254

Обзор        254

Утилиты логического резервирования        259

Раздел 8. Репликация        266

Физическая репликация        266

Обзор        266

Создание реплики        270

Смена ролей        276

Логическая репликация        285

Обзор архитектуры публикация-подписка        285

Идентификация строк        288

Настройка        290

Особенности        295

Расширения        300

Раздел 9. Платформа «Tantor»        301

Обзор        301

Введение        301

Возможности мониторинга        305

Возможности управления        315

Раздел 10. Дополнительные возможности и изменения СУБД Tantor        320

Изменение в ядре СУБД        320

Дополнительно поставляемые модули        322

Дополнительно поставляемые программы        329

Подготовлено:

Олег Иванов, Дмитрий Пронькин, Эмиль Школьник, Дарья Мишарина, Александр Горбачук

!

Последнее обновление: 30 мая 2024 г.
По всем вопросам и предложениям касательно обучения, пожалуйста, обращайтесь: [email protected]


Авторские права

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

Этот документ содержит конфиденциальную информацию и защищен авторским правом и другими законами об интеллектуальной собственности.

Вы можете скопировать и распечатать этот документ исключительно для собственного использования в рамках учебного курса «Администрирование СУБД Tantor», а также при обучении в авторизованных вендором учебных центрах.

Документ не может быть изменен каким-либо образом.

Вы не имеете права публиковать, лицензировать, размещать, передавать или распространять этот документ полностью или частично без специального разрешения ООО «Tantor Labs».

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

Отказ от ответственности за контент, продукты и услуги третьих лиц:

Данная документация может предоставлять доступ к контенту, продуктам и услугам третьих лиц или информацию о них. ООО «Tantor Labs» и ее аффилированные лица не несут ответственности и прямо отказываются от любых гарантий любого рода в отношении стороннего контента, продуктов и услуг.

ООО «Tantor Labs» и ее аффилированные лица не несут ответственности за любые убытки, издержки или ущерб, возникшие в результате вашего доступа или использования стороннего контента, продуктов или услуги.

Авторское право © 2024, ООО «Tantor Labs»

 


Раздел 1. Установка БД

Установка и управление

Установка СУБД Tantor

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

СУБД «Tantor» поставляется в скомпилированном виде в виде пакетов для пакетного менеджера операционной системы.

Перед установкой нужно свериться со списком операционных систем и их версий, для которых выпускается СУБД «Tantor».

В список поддерживаемых операционных систем входят:

Операционные системы с пакетным менеджером RedHat Packet Manager (rpm)

Операционные системы с пакетным менеджером Debian (deb)

Установка на другие операционные системы не поддерживается.

Оборудование:

https://docs.tantorlabs.ru/tdb/ru/15_6/se/install-binaries.html

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

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

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

В дистрибутивах СУБД «Tantor» перечислены те библиотеки, к функционалу которых могут обратиться утилиты и процессы экземпляра кластера.

Такие пакеты называются требуемые (requires) и относятся к зависимостям. К зависимостям могут относиться не только пакеты, но и потребности командных файлов, вызываемых при установке и других инструментов.

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

На практике же получение списка пакетов, которые нужно установить - актуальная задача.

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

Для пакетного менеджера Debian: dpkg -I tantor*.deb

Для пакетного менеджера RedHat: rpm -qp --requires tantor-se-server-15-15.4.0.el7.x86_64.rpm

Ответ утилиты состоит из перечисления пакетов и, возможно, версий пакетов и библиотек.

Например:

shadow-utils

grep

...

rpmlib(PayloadIsXz) <= 5.2-1

Значки <= и => указывают что требуются конкретные версии библиотек. В последней строке примера указаны ограничения версии пакетного менеджера, которые устанавливают проверку совместимости пакетного менеджера rpm для защиты от установки Tantor на несовместимую версию операционной системы.

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

Запустить команду можно на любой операционной Linux где установлен пакетный менеджер rpm.

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

rpm -i --test  tantor*.rpm

Пример ошибки при проверке зависимостей дистрибутива Rocky 9 на Oracle Linux 7.

warning: tantor-be-server-15-15.4.2.el9.x86_64.rpm: Header V4 RSA/SHA512 Signature, key ID f24052f5: NOKEY

error: Failed dependencies:

...

        python3-libs is needed by tantor-be-server-15-15.4.2-0.x86_64

        rpmlib(PayloadIsZstd) <= 5.4.18-1 is needed by tantor-be-server-15-15.4.2-0.x86_64

Ошибки, связанные с rpmlib указывают на неподходящий дистрибутив.

Инсталлятор

После установки необходимых пакетов, удаления конфликтующих, можно скачать  инсталлятор: https://public.tantorlabs.ru/db_installer.sh

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

Утилита скачает нужный дистрибутив.

Для скачивания коммерческих версий нужно установить переменные окружения:

export NEXUS_USER="имя"

export NEXUS_USER_PASSWORD="пароль"

export NEXUS_URL="nexus.tantorlabs.ru"

./db_installer.sh --edition=se

Возможные ошибки:

1) Конфликт может возникнуть если был установлен клиент (tantor-se-client-15_15.4.0_amd64.deb) так как пакет с сервером Tantor включает в себя библиотеки клиента. В этом случае инсталлятор выдаст ошибку и команду для ее устранения путем деинсталляции пакета с которым обнаружен конфликт:

E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution).

После запуска apt --fix-broken install, эта утилита запросит подтверждение на деинсталляцию пакета.

2) Инсталлятор создает файл /etc/apt/sources.list.d/tantorlabs.list или /etc/yum.repos.d/tantorlabs.repo и в последующем можно будет не устанавливать переменные окружения. Если будет ошибка аутентификации или захочется не аутентифицироваться, то нужно будет стереть указанные файлы. Аутентификационные данные для скачивания дистрибутива позволяет только скачать коммерческие дистрибутивы и его сохранение в файле tantorlabs.list не рассматривается как брешь в защите.

3) У инсталлятора отсутствует параметр --install-fromfile

Используется версия инсталлятора ниже 23.12.21. Нужно скачать новую версию.

Локальная установка

Tantor Basic Edition (BE) доступна для оценочного использования.

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

export NEXUS_URL="nexus-public.tantorlabs.ru"

Затем можно запустить инсталлятор, задав желаемые параметры:

./db_installer.sh --edition=be --major-version=16 --do-initdb

Можно указать основную версию и нужно ли создавать кластер после инсталляции. Также кластер можно создать после инсталляции утилитой initdb.

Инсталлятор позволяет устанавливать любые сборки СУБД Tantor из файлов пакетов. Это может быть полезно, если хост не имеет доступа в интернет.

Прежде чем приступить к установке, убедитесь, что вы загрузили правильный бинарный пакет, совместимый с вашей операционной системой и архитектурой. Файл должен иметь расширение .deb для систем на основе Debian, .rpm для систем на основе Red Hat.

Чтобы начать установку, перейдите в каталог, где находится загруженный файл. Убедитесь, что установочный скрипт db_installer.sh присутствует и имеет нужные права на выполнение.

Локальная установка выполняется командой:

./db_installer.sh --do-initdb --edition=se --major-version=16

--from-file=./tantor-se-server-16_16.1.0_amd64.deb

Нужно указать параметром --major-version=16 основную версию и она должна совпадать с версией (обычно присутствует в названии файла пакета), иначе инсталлятор может создать директорию с неверным номером версии.

Также можно установить пакет не пользуясь установочным скриптом, а используя пакетный менеджер операционной системы:

rpm -i tantor*.rpm или dpkg -i tantor*.deb

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

Недостатком может являться то, что программный код (обёрток над пакетным менеджером) может добавлять ошибки. Например, не предусматривать все возможные особенности конфигурирования операционной системы.

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

В процессе установки:

  1. создается или модифицируется пользователь для СУБД Tantor, из под которого будут запускаться процессы и который будет являться владельцем директорий, относящихся к кластерам баз данных. Пример команды создания пользователя и именем postgres:
  2. useradd -r -g postgres -c "Tantor database server" -d /var/lib/postgresql
    -s /bin/bash postgres

Менять имя пользователя postgres на другое исходя из целей безопасности не нужно.

  1. создается директория /opt/tantor/db/16 в которой располагаются исполняемые и вспомогательные файлы СУБД Tantor.
  2. создается файл описателя службы
    /usr/lib/systemd/system/tantor-se-server-16.service для того чтобы можно было запускать экземпляр, обслуживающий кластер баз данных. Кластер баз данных представляет собой директорию в файловой системе хоста (синонимы: компьютер, узел, сервер) на котором было установлено программное обеспечение СУБД Tantor.

Клиенты СУБД Tantor не имеют прямого доступа к файлам. Для того чтобы программы-клиенты могли «работать с СУБД» (посылать команды на языке SQL, получать данные) на хосте нужно запустить набор процессов, которые будут читать и писать в директорию кластера и держать соединение («сокет») с клиентской программой. Такой набор процессов и память, которую они используют в операционной системе хоста называют «экземпляром» (instance) или экземпляром кластера баз данных Tantor. Проверить статус службы можно командой: systemctl status tantor-se-server-16

  1. создается файл /etc/ld.so.conf.d/tantor-se-16.conf  

Посмотреть список разделяемых библиотек, загруженных в кэш /etc/ld.so.cache можно командой ldconfig -p | grep tantor. Можно проверить, что в переменной окружения LD_PRELOAD отсутствуют библиотеки, которые могут перекрыть библиотеки СУБД Tantor, так как LD_PRELOAD превалирует.

  1. создается директория /var/run/postgresql и файл: /usr/lib/tmpfiles.d/tantor-db.conf
            Файл используется стандартной службой очистки временных файлов. Директория является директорией по умолчанию для файлов Unix socket СУБД Tantor (параметр конфигурации (unix_socket_directories). В старых версиях PostgreSQL использовалась директория "/tmp" которая по инерции может упоминаться в документации и руководствах.
    Можно проверить, что в директории
    /usr/lib/tmpfiles.d отсутствуют другие файлы, которые могли остаться от предыдущих инсталляций postgresql, в которых указана та же самая директория, но с другими параметрами.

systemctl status systemd-tmpfiles-*
systemd-tmpfiles[]: /usr/lib/tmpfiles.d/tantor-db.conf:1: Duplicate line for path "/run/postgresql", ignoring

  1. создаётся директория /var/lib/postgresql/tantor-se-16/data
    это директория по умолчанию для файлов кластера. Утилиты СУБД Tantor узнают о местоположении директории кластера либо ключём (параметром утилиты) -D , либо из переменной окружения PGDATA. Поэтому в устной речи эту директорию называют «PGDATA».
  2. конец файла /var/lib/postgresql.bash_profile добавляются строки:

export PATH=$PATH
export PATH=/opt/tantor/db/16/bin:$PATH

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


После установки

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

В некоторых пакетных дистрибутивах PostgreSQL имеются утилиты pg_controlcluster, pg_createcluster, являющиеся обёртками для стандартных утилит pg_ctl, initdb. Разработчики таких дистрибутивов предполагают, что это упрощает работу с несколькими кластерами на одном узле. СУБД Tantor эти утилиты не использует. Облачные дистрибутивы, где востребована работа большого числа экземпляров могут использовать другие сборки (синоним forks, «форки») PostgreSQL.

После установки можно сделать следующее:

  1. установить переменную окружения в файле:

/var/lib/postgresql.bash_profile

export PGDATA=/var/lib/postgresql/tantor-se-16/data

это упростит запуск утилит управления кластером, которые мы рассмотрим позднее pg_ctl, pg_controldata, pg_backup и других - им не нужно будет указывать параметр запуска -D путь_к_PGDATA.

  1. создать кластер, если он не был ещё создан
  2. запустить кластер systemctl start tantor-se-server-16
  3. если автоматический запуск экземпляра был отключен (по умолчанию включён), то включить: systemctl enable tantor-se-server-16
  4. версию СУБД Tantor можно узнать функцией tantor_version()
  5. перейти к настройке параметров кластера, настроить инструменты управления и мониторинга кластера Платформа Tantor, pgAdmin.
  6. деинсталляция (например, предыдущей версии) выполняется пакетным менеджером. Для систем на основе Debian apt-get remove tantor-se-server-16

https://docs.tantorlabs.ru/tdb/ru/15_6/se/binary-download-execute.html 

Создание кластера утилитой initdb

Кластер создается утилитой командной строки initdb. Утилита может вызываться инсталлятором и утилитой pg_ctl.

initdb запускается из-под пользователя операционной системы postgres.

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

При запуске экземпляра проверяются разрешения на саму директорию PGDATA:

  1.  разрешения должны быть 0700 (drwx --- ---) или 0750 (drwx r-x ---)
  2.  владельцем должен быть пользователь postgres.

При создании кластера нужно выбрать настройки локализации, которые нельзя изменить после создания кластера (для создаваемых при создании кластера баз данных postgres template0 template1), но можно выбирать для баз данных создаваемых после создания кластера:

  1. LC_COLLATE правила сортировки текста
  2. LC_CTYPE классификация символов (заглавные буквы, прописные буквы, символы цифр и другие классы символов)
  3. схему кодирования символов LOCALE - третью часть значения после точки.

Эта часть должна быть UTF8 или одной из поддерживающих кириллицу кодировок. Не все комбинации языка, страны, кодировки могут быть доступны в операционной системе. Например, отсутствует ru_GB.iso88595. Для однобайтных кодировок можно выбрать комбинацию (язык_ТЕРРИТОРИЯ.кодировка) ru_RU.iso88595, так как такая LOCALE обычно присутствует в поддерживаемых СУБД Тантор операционных системах.

Параметры локализации можно задать в параметрах initdb --locale=en_US.UTF8 --lc-collate=en_US.UTF8 --lc-ctype= en_US.UTF8 --locale-provider={libc|icu} --encoding=UTF8

Если не указывать параметры, то используются переменные окружения. Получить их список можно командой locale. Список допустимых комбинаций locale -a. Настроить dpkg-reconfigure locales.  libc - стандартный провайдер. Параметр &ndash;encoding имеет смысл задавать, если в значении LOCALE нет кодировки (после точки) и есть несколько допустимых (совместимых) вариантов.

При выборе между UTF8 и iso88595 (или cp1251) можно учитывать, что в UTF8 кириллические символы занимают больше места - два байта вместо одного. Однако, приложениям может требоваться хранение, например, фамилии клиента на его национальном языке. Про однобайтовую кодировку koi8: её не стоит использовать из-за того, что бинарное сравнение символов не соответствует лингвистическому.

Параметры, на которые обратить внимание:

-k -g явно включить контрольные суммы для блоков данных (для записей WAL они включены) и установить менее ограничивающие разрешения на создаваемые файлы и директории 0755 (ноль означает, что это  восьмеричное число).

--auth --auth-host --auth-local

-D путь к PGDATA

 --wal-segsize число в мегабайтах. По умолчанию 16Мб. Значение должно быть степенью двойки. Этот параметр можно изменить после создания кластера утилитой pg_resetwal --wal-segsize=новый_размер.

Задает размер файла журнала предзаписи (синонимы WAL-файл, WAL-сегмент). Меняют либо по причине большого количества файлов одной директории, либо по причине того, что максимальный размер буфера журнала в разделяемой памяти (wal_buffers) ограничен размером WAL-файла. Влияние размера WAL-буфера на производительность нелинейная.


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

Утилита управления экземпляром pg_ctl

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

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

Основные команды, которые можно использовать с pg_ctl:

start - запуск экземпляра

stop  -m smart | fast | immediate - остановка

Перед остановкой промышленного кластера рекомендуется выполнять контрольную точку, то есть давать команду checkpoint. Это уменьшает время на остановку.

restart - перезапуск, эквивалентен остановке и запуску, поэтому могут использоваться параметры которые задаются при остановке.

reload - перечитывает файлы конфигурации без остановки экземпляра

status - выводит статус экземпляра

Для запуска экземпляра нужно указать директорию кластера - PGDATA. Это можно сделать установив переменную окружения перед запуском pg_ctl или указав в параметре -D путь к директории.

Процесс postgres

pg_ctl запускает процесс postgres, который порождает (fork) остальные процессы экземпляра, и прослушивает входящие соединения. У процесса postgres есть параметры, которые ему может передать pg_ctl. В старых версиях PostgreSQL процесс postgres назывался postmaster.

Для передачи параметров конфигурации от pg_ctl к postgres используется ключ -o. Например,

pg_ctl start -o "--config_file=./postgresql.conf --work_mem=8MB"

также можно использовать синтаксис:

pg_ctl start -o "-c config_file=./postgresql.conf -с work_mem=8MB"

Посмотреть список параметров, которые можно передавать postgres:

 postgres --help

Параметр --single запускает процесс postgres в режиме одного пользователя и одного процесса:

postgres --single

PostgreSQL stand-alone backend 16.1

backend> vacuum full

Для выхода из этого режима используется комбинация клавиш Ctrl+D.

Это не psql, команд psql в этом режиме нет, только команды которые может принимать серверный процесс (синоним backend).

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

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

Управление экземпляром через systemctl

В поддерживаемых СУБД Tantor операционных системах семейства Linux для запуска служб используется systemd.

СУБД Танатор скомпилирован с опцией --with-systemd обеспечивающей поддержку всего функционала systemd. В дистрибутиве поставляется файл описания службы /usr/lib/systemd/system/tantor-se-server-16.service и администратору не требуется его создавать.

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

По умолчанию установлен таймаут 5 минут параметром TimeoutSec=300 в этом файле.

systemd убьет экземпляр, если он не запустится в течение этого времени. На промышленных серверах восстановление после сбоя по журналам может занять значительное время. Значение infinity в таких случаях рекомендуется и отключает логику таймаута.

Во время работы сервера его PID сохраняется в файле postmaster.pid в PGDATA. Это используется для предотвращения запуска нескольких экземпляров сервера в одном каталоге данных и также может использоваться для выключения сервера.

В случае если процессы экземпляра погашены, а файл postmaster.pid мешает запустить экземпляр, файл postmaster.pid можно удалить.

systemctl - главная команда для работы с systemd. По умолчанию запускается с правами root.

Запуск экземпляра:

systemctl start tantor-se-server-16.service

Суффикс ".service" можно не писать, так как он используется по умолчанию.

Если при запуске экземпляра утилитой systemctl выдается ошибка:

Starting Tantor Special Edition database server 16...

pg_ctl: another server might be running; trying to start server anyway

lock file "postmaster.pid" already exists

HINT:  Is another postmaster running in data directory "/var/lib/postgresql/tantor-se-16/data"?

pg_ctl: could not start server

это может означать, что экземпляр запущен не через systemd, а утилитой pg_ctl и systemd не может ни запустить, ни остановить экземпляр, так как он был запущен утилитой pg_ctl. Можно проверить список процессов в операционной системе. systemd использует для запуска/остановки и других действий утилиту pg_ctl.

Команда systemctl stop tantor-se-server-16 в таком случае не может остановить экземпляр, результат она не выдаёт и может возникнуть ложное впечатление, что экземпляр погашен.

Проверить добавлен ли экземпляр в автозапуск можно командой systemctl is-enabled tantor-se-server-16


Три режима остановки экземпляра

Экземпляр можно остановить командой pg_ctl stop.

Синтаксис команды:

pg_ctl stop [-D каталог_данных]
[-m s[mart] | f[ast] | i[mmediate] ] [-W] [-t 
секунды] [-s]

На выбор есть три режима:

smart - запрещает новые подключения и ждёт добровольного отсоединения существующих сессий. А этого можно ждать часами, при этом новые подсоединения невозможны, а это простой. В Oracle Database такой режим называется «shutdown normal». Таким образом, режим smart не практичен. Однако, в отличие от Oracle Database, после подачи сигнала на остановку в режиме smart можно подать сигнал на остановку в режиме fast. В Oracle Database же можно будет погасить экземпляр только в режиме «abort».

Поэтому если вы запустили режим smart, то имеете возможность погасить экземпляр в режиме fast.

fast - запрещаются новые подключения, всем серверным процессам отправляется сигнал прервать транзакции и завершиться (сигнал linux SIGTERM 15). Затем завершаются оставшиеся фоновые процессы экземпляра в правильном порядке. Одним из последних действий выполняется контрольная точка. В Oracle Database такой режим называется «shutdown immediate». В отличие от Oracle Database откат транзакций в СУБД Tantor выполняется моментально, поэтому задержка в остановке связана, в основном, определяется длительностью выполнения контрольной точки.

fast режим остановки по умолчанию для остановки и через pg_ctl stop и через systmemctl stop.

На промышленных кластерах с большим объемом памяти используемой экземпляром можно минимизировать время остановки экземпляра, то есть время простоя. Для этого перед остановкой экземпляра нужно инициировать выполнение контрольной точки командой checkpint. После выполнения checkpoint послать сигнал на остановку экземпляра. В этом случае, контрольной точке которая всё равно будет выполнена при остановке экземпляра (финальная контрольная точка) в режиме smart или fast, придется записать на диск меньше данных и финальная контрольная точка выполнится быстрее.

В режимах smart и fast все изменившиеся в памяти данные (которые нужно сохранить, «защищаемые журналом предзаписи») по контрольной точке записываются в файлы, все файлы синхронизируются на один момент, информация об успешной остановке экземпляра записывается в управляющий файл pg_control. Это называется «корректной остановкой». При последующем запуске экземпляра по управляющему файлу определяется, что экземпляр был корректно остановлен и чтения журналов WAL не требуется.

Остановка экземпляра

immediate - режим немедленного выключения. Родительский процесс postmaster отправит сигнал немедленной остановки (SIGQUIT 3) всем остальным процессам и будет ожидать их завершения. Если какой-либо процесс не завершится в течение 5 секунд, ему будет отправлен сигнал SIGKILL (9). Дальше остановится сам процесс postmaster. Это приведет к «восстановлению» (путем повторного воспроизведения журнала WAL) при следующем запуске экземпляра. Рекомендуется использовать только в крайних случаях, например, подвисании (отсутствии дисковой активности, прогресса) остановки в режиме fast. В Oracle Database такой режим называется «shutdown abort».

Использование pg_ctl stop наиболее удобный способ погасить экземпляр, но можно послать сигнал процессу postgres напрямую:

kill -INT `head -1 $PGDATA/postmaster.pid`

Обратите внимание, что кавычки обратные, а не апострофы.

Сигнал SIGKILL (9) посылать процессу postgres не стоит, так как общая память и семафоры не освободятся до перезагрузки операционной системы или до их освобождения вручную командой ipcrm. Также серверные и фоновые процессы могут остаться в памяти. Посмотреть сегменты общей памяти и семафоры можно командой операционной системы ipcs, а освободить ipcrm.

Не стоит посылать сигнал SIGKILL (9) и другим процессам экземпляра, в том числе серверным (как это принято при работе с Oracle Database), это может привести к немедленной остановке экземпляра.

Для отсоединения сессий и прерыванию выполняющейся команды (в чужой сессии без её прерывания) в СУБД Tantor удобно использовать функции pg_terminate_backend (посылается SIGTERM 15 серверному процессу) и pg_cancel_backend (посылается SIGINT 2).

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

2) в управляющий кластер был записан статус корректной остановки кластера: pg_controldata | grep state

Database cluster state:               shut down

https://docs.tantorlabs.ru/tdb/ru/15_6/se/server-shutdown.html 


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

Утилиты управления (обёртки для команд SQL)

В директории /opt/tantor/db/16/bin путь к которой добавляется для пользователя postgres в переменную окружения PATH в процессе инсталляции находятся утилиты для работы с кластером баз данных. Утилиту initdb мы рассмотрели. Дальше рассмотрим основную утилиту - терминальный клиент psql, которая позволяет передавать на выполнение команды SQL.

Часть действий администратора кластера выполняется не командами SQL (или удобнее выполнять) и для таких действий поставляются утилиты командной строки. Часть из них рассмотрим в течение курса.

Утилиты-оболочки (синоним обёртки, wrappers) для некоторых команд SQL (которые можно послать на выполнение утилитой psql). Иногда удобно выполнять действия в кластере баз данных скриптами командной строки и в таких скриптах удобно использовать утилиты-оболочки вместо написания вызова команды через psql:

psql -c "КОМАНДА SQL"

Разницы в результате между использованием утилит-оболочек и команд SQL нет.

clusterdb - оболочка для команды SQL CLUSTER

createdb - оболочка для команды CREATE DATABASE. Разницы создавать базу данных этой утилитой или командой нет

createuser - оболочка для команды CREATE ROLE

dropdb - оболочка для команды DROP DATABASE

dropuser - оболочка для команды SQL DROP ROLE

reindexdb - оболочка для SQL-команды REINDEX

vacuumdb - оболочка для команды VACUUM

vacuumlo - к вакуумированию (VACUUM) не имеет отношение. vacuumlo удобная для периодического запуска утилита удаления (вычистки) осиротевших больших объектов из баз данных кластера. Автоматизировать удаление осиротевших больших объектов можно разными способами (например, триггерами), эта утилита один из способов. Расширение "lo" содержит функцию lo_manage для использования в триггерах, предотвращающих появление осиротевших больших объектов.

Описание утилит:

https://docs.tantorlabs.ru/tdb/ru/15_6/se/reference-client.html 

Утилиты управления резервированием

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

К резервированию кластера относятся утилиты:

pg_archivecleanup используется в значении параметра archive_cleanup_command для удаления ненужных файлов WAL на физической реплике (резервном кластере)

pg_basebackup - утилита создания резервных копий кластера (бэкапов) для клонов, реплик и просто для хранения. Может копировать директорию или вытягивать файлы по сети используя для этого протокол репликации

pg_dump - создает логическую копию объектов базы данных

pg_dumpall - создает логическую копию всего кластера или общих объектов кластера в виде текстового скрипта создания баз данных и объектов. Используется в процедурах обновления основной версии, переноса кластера на другие платформы, сборки, форки PostgreSQL. Представляет интерес параметр -g позволяющий выгружать общие объекты кластера.

pg_receivewal - используется для вытягивания по протоколу репликации содержимого файлов WAL (поточного архива). Обычно используется для организации хранения журналов WAL на узлах с бэкапами.

pg_recvlogical - инструмент для использования в логической репликации. Используется редко.

pg_resetwal очищает журнал WAL. Используется с параметром --wal-segsize для изменения размера WAL-сегментов, если захочется изменить их размер после создания кластера. Процедура требует аккуратности и знания что произойдёт с бэкапами и именами файлов WAL. Также для процедуры изменения размера WAL-сегментов критически важно, чтобы кластер был корректно остановлен. Меняют либо по причине большого количества файлов в одной директории, либо по причине того, что максимальный размер буфера журнала в разделяемой памяти (wal_buffers) ограничен размером WAL-файла. Влияние размера WAL-буфера на производительность нелинейна.

pg_restore - утилита восстановления из логических бэкапов созданных утилитой pg_dump в части режимов (в других режимах для восстановления используется psql)

pg_waldump - показывает содержимое WAL-сегментов, используется для отладки в сложных случаях восстановления

https://docs.tantorlabs.ru/tdb/ru/15_6/se/reference-server.html 

Утилиты управления (другие)

Утилиты для обновления версий СУБД Tantor и для настройки отказоустойчивости:

pg_amcheck - относится к стандартному расширению (PostgreSQL extension) amcheck, которое имеет набор функций для проверки отсутствия повреждений в объектах в которых физически хранятся данные, называемых отношения (relations). Отношениями (синоним «класс») называются таблицы, индексы, последовательности, представления, внешние (foreign) таблицы, материализованные представления, составные типы. Если функционал amcheck сообщает о повреждениях, то они действительно есть, ложные срабатывания исключены.

pg_checksums - включение/отключение подсчета контрольных сумм блоков данных и проверка блоков данных кластера. В Oracle Database аналог - утилита dbv (dbverify).

pg_rewind - используется для синхронизации кластеров, обычно для восстановления бывшего мастера (основной, primary кластер) после аварийного переключения на физическую реплику (резервный, standby кластер), а также в процедурах апгрейда (перехода на новую основную версию).

pg_upgrade - для апгрейда.

pg_test_fsync - используется при настройке параметров записи в WAL сегменты, влияющих на отказоустойчивость.

Полезные утилиты

pg_config - информация о параметрах инсталляции и сборки СУБД Tantor.

pg_controldata - выводит в текстовом виде содержимое управляющего файла кластера $PGDATA/global/pg_control.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/reference-client.html 


Утилиты управления (продолжение)

pg_isready проверка, что кластер принимает соединения, аналог psql -c "\q". Утилитой только удобнее получать результат, но в psql можно указать дополнительные команды для проверки доступности объектов с точки зрения конкретного клиентского приложения.

oid2name - удобная утилита для поиска к какому объекту относится файл в директории кластера (PGDATA) и табличных пространств, а также другой информации о принадлежности файлов и директорий объектам кластера. Аналогичные действия можно выполнить и командами SQL и функциями SQL, но это гораздо сложнее.

postgresql-check-db-dir - скрипт поверхностной проверки структуры директории PGDATA, вызывается systemd перед вызовом pg_ctl для запуска экземпляра, чтобы убедиться, что в директории PGDATA лежит что-то похожее на директорию кластера.

vacuum_maintenance.py и другие скрипты на языке Python, используются расширением pg_partman секционирования («партиционирования», partitioning) таблиц.

pg_repack - расширение, которое позволяет не блокируя полностью объект реорганизовать файлы в которых хранятся данные. Аналог команды VACUUM FULL, только без монопольной блокировки.

Рассмотренные ранее в этой главе:

pg_ctl - управляет экземпляром кластера.

initdb - создает кластера.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/reference-server.html 


Терминальный клиент psql

Терминальный клиент psql

В программном обеспечении СУБД Tantor есть терминальный клиент (утилита командной строки) psql.

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

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

psql -f файл_скрипта.sql

psql -c "CREATE SCHEMA sh; CREATE TABLE sh.t (n numeric);"

У psql есть файлы конфигурации. Глобальный лежит в директории на которую указывает параметр pg_config --sysconfdir.

Для сборок Tantor - это файл /opt/tantor/db/16/etc/postgresql/psqlrc

Локальный для пользователя операционной системы лежит в его домашней директории, значение по умолчанию ~/.psqlrc Местоположение локального файла может быть переопределено переменной окружения PGCONFIG.

По умолчанию файлы не созданы, но можно создать. В Oracle Database аналогичные файлы называются "glogin.sql".

Оба файла могут быть сделаны специфичными для версии psql путем добавления дефиса и идентификатора основной или минорной версии «Tantor SE» к имени файла, например ~/.psqlrc-16 или ~/.psqlrc-15.4. Все файлы применяются, но более специфичный файл превалирует.

С помощью этих файлов можно сделать работу в psql удобнее.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/app-psql.html#psql 

psql: подключение к базе данных

psql подключается к конкретной базе данных в кластере. Для подсоединения к базе нужно пройти аутентификацию, которая обычно настраивается отдельно для локальных подсоединений через Unix-сокеты, сетевых соединений с того же хоста на адрес localhost (127.0.0.1) и соединений с других хостов. СУБД Tantor поддерживает разнообразные способы аутентификации, они будут рассмотрены в следующих главах курса. Аутентификация возможна и без пароля, но сессия должна быть сопоставлена с ролью (пользователем) кластера. Подсоединение без сопоставления с ролью заранее созданной в кластере возможно только в однопользовательском режиме (single mode). В однопользовательском режиме подключение выполняется под пользователем который неявно наделяется правами суперпользователя.

Роль (ROLE) и пользователь (USER) синонимы и абсолютно одинаковые понятия. Роли, создаваемые командами, одинаковы, за исключением того, что CREATE ROLE по умолчанию создает роль с атрибутом NOLOGIN.

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

Подключиться одновременно к нескольким базам даже из одного кластера кластере нельзя. Базы изолированы друг от друга с точки зрения безопасности и привилегий. Для одновременной работы с таблицами в разных базах данных даже если они находятся в одном кластере можно использовать расширения postgres_fdw (Foreign Data Wrapper) или dblink. Для копирования данных между базами данных можно использовать поточную передачу данных («пайп») и утилиту pg_dump ... | psql ...

psql: параметры подключения

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

-U роль или --username=роль значение по умолчанию имя пользователя операционной системы из-под которого запущен psql

-d имя_базы или --dbname=имя_базы значение по умолчанию имя роли, заданное параметром -U

-h хост или --host=хост значение по умолчанию /var/run/postgresql (на стороне экземпляра это же значение задано при сборке и отображается в параметре unix_socket_directories) то есть используется локальное соединение через Unix-сокет.

Если psql или другие утилиты выдают ошибку.

could not connect to server: No such file or directory

        Is the server running locally and accepting

        connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

Возможно запускается утилита старой версии (например, из пути /usr/bin/psql).

Версия проверяется psql -V

помимо передачи параметра -h можно указать директорию Unix-сокетов в переменной окружения PGHOST, например, export PGHOST=/var/run/postgresql.

-p порт или --port=порт значение по умолчанию 5432.

Для локальных соединений через Unix-сокет порт тоже используется, так как директория одна и та же для всех кластеров. Если это директория в файловой системе, то в ней основной процесс postgres создаёт файл у которого суффикс является номером порта. Например, /run/postgresql/.s.PGSQL.5432.

Также можно использовать сокращенный синтаксис: psql параметры имя_базы имя_пользователя. Например, psql postgres postgres.

Полезная команда psql для вывода деталей подсоединения: \conninfo

You are connected to database "postgres" as user "postgres" via socket in "/var/run/postgresql" at port "5432".

Выдаётся имя роли, из-под которой было создано соединение (пройдена аутентификация). Команды SET ROLE и SET SESSION AUTHORIZATION не меняют результат \conninfo

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

\c имя_базы имя_роли хост порт

Если какие-то параметры не хочется указывать, а хочется использовать значения текущего соединения, то вместо параметра в его позиции нужно использовать символ тире. Тире в конце можно не указывать. Например:

\c - user1

You are now connected to database "postgres" as user "user1".

\c - - localhost

You are now connected to database "postgres" as user "user1" on host "localhost" (address "127.0.0.1") at port "5432".

Если новое соединение не может быть установлено, сохраняется прежнее.

Получение справки по командам psql

После установки СУБД Tantor можно запустить на сервере psql без параметров и psql подсоединяется локально через Unix-сокет к базе данных postgres под ролью postgres.

команды psql начинаются на обратный слэш \

Узнать какие команды SQL формирует psql чтобы исполнить команды, начинающиеся на \d (describe - получить описание объекта) можно установив параметр:

\set ECHO_HIDDEN on

Если текст не помещается на экран используется функционал «постраничного вывода» (pager), вы увидите двоеточие.

По нажатии клавиши <ENTER> высветится еще одна строка.

Если нужно высветить следующую страницу, то после двоеточия нужно набрать символ «z»

Если вернуться к предыдущей странице - символ «b» (back)

Если хочется прервать вывод можно набрать символ «q» (quit)

Если хочется получить помощь и узнать какие есть еще комбинации клавиш то можно набрать после двоеточия букву «h» (help)

Отключить постраничный вывод можно командой \pset psger off

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

История команд по умолчанию доступна по нажатию стрелок вверх/вниз на клавиатуре. История команд набранных интерактивно в psql хранится в файле ~/.psql_history. Его местоположение может быть переопределено переменными окружения HISTFILE или PSQL_HISTORY, но смысла в этом нет. Рядом с ~/.psql_history например лежит файл ~/.bash_history с историей команд терминала операционной системы. Названия файлов начинающиеся с точки в Линукс считаются «скрытыми» файлами. Например, команда ls без параметров не показывает такие файлы.

psql может запускаться с клиентской машины из сборок, отличных от сборок Tantor. psql работает лучше с серверами той же или более старой основной версии. При подключении к более новой версии СУБД могут отказаться работать команды psql (те который начинаются на обратный слэш).

Форматирование вывода psql

Посмотреть текущие настройки форматирования можно набрав \pset

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

\watch секунд (выход <CTRL+X>)

\a включить/выключить выравнивание столбцов по вертикали;

\t включить/выключить отображение заголовка и итоговой строки (header and footer).

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

\pset fieldsep ' '

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

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

postgres=# \timing

Timing is on.

postgres=# \timing

Timing is off.

Вывод результата в формате HTML

Если количество столбцов большое и терминальный клиент с пропорциональным шрифтом неудобен для отображения, psql может сформировать результат не в текстовом формате, а в формате HTML. За это отвечает параметр -H или параметр \pset format html

Пример команды, посылающей SQL команду на выполнение и запускающую браузер с результатом в формате HTML:

psql -c "команда;" -H -o f.html | xdg-open f.html

Одной строкой можно получить результат больших выборок в читаемом формате.

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

Вывод результата в расширенном формате

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

Переключение вывода выполняется короткой командой \x

Вернуть обычный режим можно еще раз набрав \x

В запросе обычно указывается сортировка и ограничение количества выдаваемых строк: ORDER BY и LIMIT.

Приглашение к вводу команд (промпт) psql

Нередки случаи, когда администратор дал команду «не в том окне».

Уменьшить вероятность таких случаев помогает изменение приглашения psql (промпта).

Приглашение к вводу команд (промпт) имеет значения по умолчанию, которые различают первую набранную строку в команде и последующие.

По умолчанию PROMPT2 отличается от PROMPT1 незаметными символами: = и -. Стоит обращать на них внимание.

PROMPT1, PROMPT2 и PROMPT3 задают внешний вид приглашения.

PROMPT1 выдаётся, когда psql ожидает ввода новой команды.

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

Типичным вопросом является: за что отвечает третий промпт?

PROMPT3 выдаётся при выполнении команды COPY FROM stdin, когда в терминале вводятся данные для вставки в таблицу. Завершает такой режим \.<ENTER>

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

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

Автофиксация транзакций и выполнение команд psql

Команда, начинающаяся на обратный слэш «\» обрабатывается psql. Посмотреть справку по таким командам можно командой \?

Командой \set можно посмотреть переменные psql. Часть переменных предопределена и управляет работой psql. Можно устанавливать на время до выхода из psql свои переменные и пользоваться ими как макросами.

Стоит отличать команды \set \pset set. Последняя относится к SQL и меняет параметры работы серверного процесса на уровне сессии (set session) или транзакции (set local). \pset это предопределённые параметры форматирования вывода psql.

Остальные команды посылаются как текст серверному процессу. Для отправки команды нужно ввести «;» и возврат каретки (клавиша <ENTER> на клавиатуре).

В psql есть нестандартные команды \g \gx \gexec \gset \g которые могут заменять стандартно используемый символ ";" Эти нестандартные команды имеют широкие возможности, но их использование в скриптах делает скрипты не переносимыми - скрипты не смогут выполняться нигде, кроме psql.

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

Если вы хотите очистить буфер, можно набрать \r (сокращение от \reset).

Посмотреть содержимое буфера или последней команды если буфер пуст \p (сокращение от \print).

psql по умолчанию работает в режиме автоматической фиксации транзакции AUTOCOMMIT. Режим автофиксации по умолчанию используется также в программах на языке Java, в спецификации JDBC. Oracle Database в своём терминальном клиенте sqlplus не использует режим автофиксации.

Если вы хотите отключить режим автофиксации, вы можете отключить этот режим в системном файле psqlrc или в вашем файле ~/.psqlrc или в своей сессии. За это отвечает параметр:

\set AUTOCOMMIT on

\set AUTOCOMMIT off

Переменные psql

Переменные psql устанавливаются командой \set имя значение. Срок жизни до выхода из psql или до выполнения команды \unset имя.

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

Пример:

postgres=# \set TEST1 'select user'

postgres=# :TEST1;

   user  

----------

 postgres

(1 row)

postgres=# select * from (:TEST1);

По умолчанию для команд редактирования \ef \ev \e используется vi. Переопределить редактор можно установив переменную окружения

export PSQL_EDITOR=/usr/bin/mcedit

Вместо PLQL_EDITOR можно использовать имена EDITOR или VISUAL.

Либо находясь в psql дать команду \setenv PSQL_EDITOR /usr/bin/mcedit

Либо вставить команду \setenv PSQL_EDITOR /usr/bin/mcedit в файле ~/.psqlrc или глобальном /opt/tantor/db/16/etc/postgresql/psqlrc

В разделе «Окружение» в документации https://docs.tantorlabs.ru/tdb/ru/15_6/se/app-psql.html#APP-PSQL-ENVIRONMENT указаны переменные окружения операционной системы на которые реагирует psql.

Часто используемые переменные: PGUSER PGDATABASE PGHOST PGPORT. Они позволяют настроить подсоединение psql без указания параметров к любой базе.

Переменные окружения операционной системы можно устанавливать командой \setenv в том числе в файле ~/.psqlrc или глобальном /opt/tantor/db/16/etc/postgresql/psqlrc. Другими командами типа \set \pset \! export переменные окружения не устанавливаются.

Выполнение командных файлов в psql

В psql можно выполнить команду операционной системы не выходя из psql. Для этого используется команда \! команда_линукс

Для вывода результата выполнения команд (POSIX output stream) в файл операционной системы можно использовать команду \o имя_файла. На экран при этом результаты выдаваться не будут.

Для выполнения командного файла можно использовать \i имя_файла

\o checkpoint.sql

select 'checkpoint;' \g (tuples_only=on format=unaligned)

\o  -- вернуть вывод на экран

\i checkpoint.sql

Также команды из файла (скрипта) можно выполнить так:

psql < checkpoint.sql

psql -f checkpoint.sql

При этом ставить последней в файле команду выхода необязательно, psql сам закончит работу дойдя до конца файла (в отличие от утилиты sqlplus Oracle Database).

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

postgres=# select 'checkpoint;' \gexec
CHECKPOINT


Графическая утилита pgAdmin

pgAdmin

pgAdmin - свободно распространяемая графическая программа для работы с кластерами PostgreSQL, в том числе СУБД Tantor.

Утилита выпускаются: 3 версии pgAdmin3 - оконный интерфейс, разработка завершилась в 2016 году и в 4 версии pgAdmin4 веб-интерфейс, но с удобной возможностью создать ссылку на десктопе. Многие администраторы и разработчики используют pgAdmin. Она позволяет использовать пошаговую отладку хранимых подпрограмм - является клиентским интерфейсом к функционалу свободно распространяемой библиотеки pldebugger реализующей серверную часть функционала отладчика.

pgAdmin3 не работает с PostgreSQL 15 и новее, так как при подсоединении обращается к столбцу datlastsysoid таблицы pg_database системного каталога кластера, который был удалён в 15 версии (https://pgpedia.info/postgresql-versions/postgresql-15.html)

pgAdmin4 может быть установлен в Астра Линукс 1.7 Эта версия основана на Debian 10 Buster (https://wiki.astralinux.ru/pages/viewpage.action?pageId=53646577).

Значит ищем дистрибутивы в поддиректории «buster»

https://ftp.postgresql.org/pub/pgadmin/pgadmin4/apt/buster/dists/pgadmin4/main/binary-amd64/

pgadmin4-server_8.3_amd64.deb

pgadmin4-desktop_8.3_amd64.deb

Устанавливать их можно командами:

dpkg -i pgadmin4-server_8.3_amd64.deb

dpkg -i pgadmin4-desktop_8.3_amd64.deb

Запускать из меню Star -> Development ->pgAdmin 4

В меню pgAdmin4: в File ->Preference s-> Paths -> Binary Paths --> PostgreSQL 16 поставить путь /opt/tantor/db/16/bin чтобы из меню Tools можно было запускать «PSQL Tool».


pgAdmin: Dashboard

Основные страниц pgAdmin:

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

Слева в Object Explorer показывается список общих объектов кластера: баз данных, ролей, табличных пространств.

В pgAdmin есть функционал отладки хранимых подпрограмм.

Для разработки приложений популярно коммерческое приложение DataGrip от JetBrains, которое интегрируется со средами разработки этой компании: IntelliJ IDEA и PyCharm. Интеграция позволяет проверять синтаксис и автозавершение команд SQL при написании программного кода.

В качестве альтернативы pgAdmin может использоваться универсальное (для разработки и для администрирования) приложение DBeaver, имеющее бесплатную версию.

Приложение можно скачать командой:

wget https://dbeaver.io/files/dbeaver-ce_latest_amd64.deb

и установить командой:

sudo dpkg -i dbeaver-ce_latest_amd64.deb

Запустить приложение можно из меню Пуск -> Development -> dbeaver-ce или командой:

/usr/bin/dbeaver-ce

pgAdmin: меню

В меню можно вызвать визард создания объектов.

pgAdmin: закладка SQL команды создания объектов

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

pgAdmin: закладка Statistics

В pgAdmin есть страница на которой отображается статистика по объектам.

pgAdmin: команда создания базы данных

Пример команды создания базы данных:

pgAdmin: визард создания таблицы

Команда создания таблицы синтаксически наиболее сложная из всех команд.

В ней есть много опций. В pgAdmin есть визард создания таблицы, опции размещены на наборе закладок.

Параметры работы автовакуума, которые можно настроить на уровне таблицы:

pgAdmin: Query Builder

Графический редактор SQL-команд.

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

pgAdmin: psql в окне

Также есть возможность запустить psql в окне pgAdmin.

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

pgAdmin: визард создания функции

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

pgAdmin: результат создания функции

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

pgAdmin: редактирование функции в окне psql \ef

В качестве текстового редактора в psql был выбран mcedit.

Этот снимок экрана иллюстрирует то, что psql запускающийся в окне pgAdmin полнофункциональный.


Раздел 2. Архитектура

Общие сведения

Клиент-сервер

Определение

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

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

Сервер базы данных (PostgreSQL сервер) - PostgreSQL сервер предоставляет доступ к базе данных и обрабатывает запросы от клиентов. Он управляет хранением данных, обеспечивает безопасность и целостность данных, управляет транзакциями и обеспечивает возможность одновременной работы нескольких клиентов. Сервер слушает определенный сетевой порт и ждет запросы от клиентов.

Клиентские приложения - Клиенты устанавливают подключение к серверу, и каждое подключение создает сеанс работы. В рамках сеанса клиент может отправлять SQL-запросы, а сервер выполняет их и возвращает результаты. Сеанс поддерживает состояние, что позволяет серверу отслеживать информацию о текущем состоянии подключенных клиентов.

Протоколы обмена данными - Для обмена данными между клиентами и сервером используются определенные протоколы, такие как TCP/IP. Обычно PostgreSQL использует протокол передачи данных по сети (TCP/IP), который обеспечивает безопасное и эффективное взаимодействие между клиентом и сервером.

Подключение и сеансы:

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

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

Функции клиента

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

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

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

Сервер PostgreSQL обеспечивает транзакционное управление, что позволяет объединять несколько операций в единую транзакцию, обеспечивая целостность данных. Этот механизм также дает возможность отката изменений в случае возникновения ошибок.

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

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

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

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

Клиентское приложение взаимодействует с сервером PostgreSQL, выполняя различные функции, необходимые для работы с базой данных. Одной из основных функций является установка соединения с сервером, что обеспечивает возможность передачи SQL-запросов.

Клиент отправляет SQL-запросы, ожидая от сервера результатов их выполнения. Эти результаты, как правило, содержат данные, которые клиентское приложение должно обработать, отобразить пользователю или использовать в дальнейшей логике программы.

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

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

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

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

Протокол подключения

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

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

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

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

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

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

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

Драйвер libpq

Драйвер libpq - это библиотека на языке программирования «C», предназначенная для обеспечения эффективного взаимодействия клиентских приложений с сервером PostgreSQL.

Установка соединения является первоначальным шагом, где libpq предоставляет функции для указания параметров, таких как хост, порт, база данных, пользователь и пароль.

Одной из ключевых возможностей драйвера является отправка SQL-запросов на сервер PostgreSQL. Это важно для выполнения различных операций, включая выборку, вставку, обновление и удаление данных. Полученные после выполнения запросов результаты могут быть обработаны с использованием механизмов, предоставленных libpq. Здесь важно выделить момент эффективной обработки ошибок в случае их возникновения.

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

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

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

В целом, libpq - важный инструмент для разработчиков на языке программирования «C», предоставляющий эффективные средства взаимодействия с базой данных PostgreSQL

Сжатие в libpq

В TantorSE и Tantor SE 1C внедрено сжатие в libpq.

В библиотеку libpq добавлена поддержка сжатия.

В конфигурацию (GUC) добавлен параметр libpq_compression, который контролирует доступные методы сжатия трафика между клиентом и сервером. Улучшение направлено на оптимизацию производительности при обмене данными между клиентскими программами и сервером.

Поскольку libpq представляет собой C API для PostgreSQL, эту функциональность могут использовать клиентские приложения и драйверы, которые написаны на «C» или на других языках, поддерживающих вызовы C API.

Библиотека libpq является основным интерфейсом для работы с PostgreSQL и используется для создания «клиентских» приложений, которые взаимодействуют с сервером PostgreSQL.

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

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

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

Слоты, зарезервированные через новый GUC (Grand Unified Configuration) reserved_connections (параметр postgresql.conf), доступны только пользователям с новой предопределенной ролью pg_use_reserved_connections.

Значение параметра superuser_reserved_connections остается в качестве окончательного резерва на случай, если reserved_connections были исчерпаны.

Поддержка архитектуры ARM64

Во всех версиях Tantor и в PostgreSQL присутствует поддержка архитектуры ARM64.

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

Поддержка архитектуры ARM64 в PostgreSQL открывает новые возможности для запуска PostgreSQL на устройствах с такими процессорами, например на смартфонах и планшетах. Это может быть полезно для разработки приложений, которые требуют локальной базы данных на таких устройствах.

Это изменение включает оптимизации и исправления ошибок, связанные с работой PostgreSQL на архитектуре ARM64. Также с PostgreSQL 14 произведены оптимизации для улучшения производительности на ARM64.

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

Повышение скорости обработки потоковых данных, в частности для ускорения операций при работе с json\text для процессоров с архитектурой ARM

В редакциях Tantor SE и Tantor SE 1C в сравнении с ванильным PostgreSQL реализовано повышение скорости обработки потоковых данных, особенно для ускорения операций при работе с json\text для процессоров с архитектурой ARM.

Патч направлен на использование модели вычислений SIMD (Single Instruction, Multiple Data), которая используется в параллельном программировании. Основное преимущество SIMD заключается в том, что она позволяет процессору одновременно выполнять одну и ту же операцию сразу над несколькими наборами данных, что может значительно ускорить обработку данных.

Что реализовано в данном функционале:

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

2. Поддержка SSE2 (Streaming SIMD Extensions 2). Добавляются внутренние компоненты, которые позволяют использовать инструкции SSE2 там, где это возможно. Это может ускорить обработку данных, особенно при работе с текстовыми и JSON данными.

3. Абстрагирование архитектурно-зависимых деталей. Патч включает поддержку для архитектуры NEON. Это расширяет возможности использования SIMD на большем количестве платформ.

4. Поддержка SIMD NEON. Патч включает использование встроенных функций SIMD NEON, что повышает производительность на архитектурах, поддерживающих NEON.

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

Оптимизация для линейного поиска для процессоров с архитектурой ARM 64

В редакциях «Tantor SE» и «Tantor SE», также реализована оптимизация для линейного поиска для процессоров с архитектурой ARM 64.

Патч помогает повысить производительность PostgreSQL на машинах с архитектурой ARM, используя более эффективные и надёжные операции атомарной синхронизации.

Данный патч модифицирует код PostgreSQL, связанный с реализацией примитива синхронизации «test-and-set» (TAS), также известного, как «atomic compare and swap» (CAS), на архитектуре ARM. Он меняет реализацию TAS с использованием старого GCC-расширения `__sync_*` на более современное и универсальное расширение `__atomic_*`, включая новую функцию `cas()`, которая использует `__atomic_compare_exchange_n` вместо предыдущего механизма TAS.


Транзакции

Понятие транзакции

Транзакция в базах данных - это концептуальная и логическая единица работы, которая представляет собой последовательность операций (или запросов), направленных на базу данных. Эта последовательность операций рассматривается как единое целое, что означает, что все операции внутри транзакции либо выполняются успешно, либо не выполняются вовсе.

Транзакция в контексте баз данных завершается фиксацией (commit) или откатом (rollback).

Таким образом, завершение транзакции происходит с фиксацией изменений в базе данных в случае успешного выполнения или с откатом изменений в случае неудачи. Этот момент является ключевым для обеспечения целостности и надежности данных в системе базы данных.

Также возможно использование автономных транзакций https://docs.tantorlabs.ru/tdb/ru/15_6/se/autonomous-transactions.html

Автономные транзакции в PL/pgSQL позволяют выполнять SQL-запросы внутри функции в отдельной транзакции с полной изоляцией.

ACID свойства

Основные свойства транзакции:

  1. Атомарность (Atomicity) - транзакция является атомарной, что означает, что все операции внутри транзакции либо успешно выполняются, либо не выполняются вообще. Если хотя бы одна операция в транзакции завершается неудачно, то все изменения, внесенные предыдущими операциями, откатываются, восстанавливая базу данных в прежнее состояние.
  2. Согласованность (Consistency) - транзакция должна приводить базу данных из одного согласованного состояния в другое. Если база данных была в согласованном состоянии до начала транзакции, она должна остаться в согласованном состоянии после ее завершения.
  3. Изолированность (Isolation) - изоляция гарантирует, что выполнение одной транзакции не влияет на выполнение других транзакций. Другие транзакции не видят промежуточные изменения текущей транзакции, пока она не завершится.
  4. Долговечность (Durability) - после успешного завершения транзакции ее результаты остаются в базе данных даже в случае сбоя системы или отключения питания. Это гарантирует, что система может быть восстановлена к последнему согласованному состоянию после сбоя.

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

Автономные транзакции

Поговорим об улучшениях в СУБД «Tantor» направленных на удобство использования.

Для версии «SE» улучшения включают в себя автономные транзакции.

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

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

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


Фоновые процессы

postmaster

postmaster в PostgreSQL - это основной процесс управления сервером базы данных. Этот процесс отвечает за запуск и управление другими процессами PostgreSQL, в том числе рабочими процессами, обработкой запросов, управлением подключениями к базе данных и обеспечением целостности данных.

Когда вы запускаете PostgreSQL, процесс postmaster стартует первым. Он слушает определенный порт (по умолчанию 5432) и ожидает входящих запросов от клиентов. Когда клиент отправляет запрос на подключение к базе данных, postmaster обрабатывает это подключение, создает новый рабочий процесс (называемый backend), который будет обслуживать запросы этого клиента.

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

Важно отметить, что начиная с PostgreSQL версии 16 и выше, термин postmaster официально заменен на postgres, но в некоторых случаях оба термина могут использоваться.

Служебные процессы

В PostgreSQL выполняются ключевые служебные процессы, обеспечивающие эффективное управление и поддержание базы данных.

Все эти процессы функционируют в оперативной памяти (ОЗУ), обеспечивая нормальную работу системы.

Эти служебные процессы взаимодействуют, обеспечивая надежное и эффективное функционирование PostgreSQL баз данных. Конкретное название и назначение пройдем позже.

Пользовательские процессы

В PostgreSQL термин «пользовательские процессы» обычно относится к процессам, которые управляются и выполняются от имени конкретного пользователя базы данных. Когда пользователь подключается к PostgreSQL, сервер создает процесс для обслуживания этого подключения. Этот процесс работает от имени пользователя, который выполнил вход.

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

В PostgreSQL пользовательские процессы часто называются «backend-процессами» или просто «backend». Каждый подключенный клиент (пользователь) к базе данных запускает свой собственный backend-процесс на сервере PostgreSQL. Этот процесс отвечает за выполнение запросов и обработку других операций, предоставляя данные пользователю. Важно отметить, что управление пользователями, их правами доступа и другими аспектами безопасности также влияет на то, как пользовательские процессы взаимодействуют с базой данных. Каждый пользователь имеет определенные привилегии, определяющие, что он может делать в контексте базы данных.

Tantor SE - увеличение производительности системы управления базами данных (СУБД) при большом количестве одновременных пользователей.

 https://docs.tantorlabs.ru/tdb/ru/15_6/se/differences.html


Структуры памяти

Буферный кэш

Структура

Область общей памяти предназначена для временного хранения данных таблиц, индексов и различных служебных структур. Термин «общая» отражает тот факт, что все процессы в системе управления базами данных имеют одинаковый уровень доступа к этой области, и изменения, внесенные одним из процессов, автоматически становятся доступными для всех остальных. Обычно основную часть этой общей памяти занимает буфер, также известный как буферный кеш, который служит для временного хранения пользовательских данных.

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

В PostgreSQL величина буферного кэша определяется параметром конфигурации под названием shared_buffers. Этот параметр задает количество памяти (в килобайтах), выделенной для буферного кэша.

Пример в конфигурационном файле postgresql.conf:

shared_buffers = '128MB'

В данном случае, буферный кэш будет занимать 128 мегабайт оперативной памяти. Размер буферного кэша влияет на производительность системы: увеличение его размера может улучшить производительность при частых обращениях к данным, но слишком большой размер может привести к уменьшению производительности из-за больших накладных расходов на управление кэшем.

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

Информация в буфере

Заголовок буфера в PostgreSQL включает в себя метаданные, необходимые для управления содержимым буферного кэша. Метаданные обеспечивают информацию о состоянии и содержании блока данных в буфере.

Заголовок буфера содержит следующие элементы:

Эти элементы заголовка буфера предоставляют PostgreSQL информацию, необходимую для эффективного управления и использования буферного кэша.

Размер страницы данных устанавливается такой же, как и страница данных на диске. Проверить размер можно с помощью параметра block_size.

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

Синхронизация информации

В PostgreSQL, как и во многих других системах управления базами данных, механизмы вытеснения в буферном кэше используются для управления ограниченным объемом оперативной памяти и эффективного хранения часто используемых данных. В PostgreSQL применяется алгоритм Least Recently Used (LRU) для механизма вытеснения данных из буферного кэша.

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

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

Несколько ключевых механизмов включают:

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

Повышение производительности СУБД при большом количестве одновременных пользователеи? (shared buffer partitions)

Во всех версиях всех СУБД Tantor улучшено функционирование СУБД при большом количестве одновременных пользователей (shared buffer partitions).

Патч повышает производительность СУБД при большом количестве одновременных пользователей (более 1500) путем увеличения числа разделов хеш-таблицы для общего буфера - shared buffers. Shared buffer - это основной буфер, который PostgreSQL использует для кэширования данных из дискового хранилища.

Этот патч изменяет значение макроса `NUM_BUFFER_PARTITIONS` со 128 на 256. Макрос определяет число разделов хеш-таблицы для общего буфера. Это позволяет сократить время ожидания блокировок, когда множество потоков или процессов пытаются получить доступ к данным в shared buffers.

Увеличение числа разделов может повысить производительность при работе с большими объемами данных и при большой конкурентной нагрузке, поскольку каждое разделение может быть заблокировано независимо. Это позволяет сократить время ожидания блокировок, когда множество потоков или процессов пытаются получить доступ к данным в shared buffer.

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

Снижение количества блокировок страниц данных в общем буфере (shared buffer)

Во всех версиях СУБД Tantor снижено количество блокировок страниц данных в общем буфере (shared buffer)

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

1. Устранение проблемы с получением двух блокировок разделов одновременно. Это создает сложную цепочку зависимостей, которая может привести к проблемам при высоком уровне параллелизма.

2. Вместо этого предлагается вначале вставить «заполнитель» в таблицу буфера. Этот «заполнитель» будет резервировать место в таблице и информировать другие бэкенды о намерении выделить этот буфер.

3. Другие бэкенды могут ожидать, используя ConditionVariable, связанную с бэкендом, выполняющим реальную работу.

4. Тег буфера, над которым работает бэкенд, сохраняется в статическую переменную. Если бэкенд по какой-либо причине прерывается, он удаляет «заполнитель» и будит ожидающие бэкенды.

5. В патче также предлагаются улучшения ConditionVariable для повышения производительности:

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


WAL

Цель создания

Буферный кэш, представляя собой временное хранилище данных в оперативной памяти, эффективно оптимизирует производительность систем управления базами данных (СУБД). Однако, при внесении изменений в данные, буфер становится «грязным», создавая потенциальные рассогласования с данными на диске. Это обстоятельство поднимает важный вопрос о том, как обеспечить целостность данных в случае сбоев.

Именно здесь на сцену выходит журнал предзаписи, или WAL (write-ahead log).

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

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

Журнал предзаписи (WAL) в PostgreSQL служит ключевым механизмом для обеспечения надежности и целостности данных.

Он выполняет несколько важных функций в системе управления базами данных (СУБД) PostgreSQL:

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

Механизм работы журнала предзаписи

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

В PostgreSQL размер сегмента журнала предзаписи (WAL segment) на диске обычно составляет 16 мегабайт. Это фиксированный размер сегмента, который является стандартным для большинства установок по умолчанию.

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-preset.html#GUC-WAL-SEGMENT-SIZE

Логическая структура

Логическая структура журнала предзаписи (WAL) в PostgreSQL включает в себя концепцию Log Sequence Number (LSN), которая играет ключевую роль в отслеживании последовательности записей и состояния WAL.

Log Sequence Number (LSN):

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

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

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

Log Sequence Number (LSN) в PostgreSQL измеряется в байтах. Он представляет собой уникальный адрес в журнале предзаписи (WAL), указывающий на конкретное место в последовательности записей.

LSN включает в себя два компонента:

LSN позволяет системе PostgreSQL отслеживать порядок записей в WAL и обеспечивает точность и последовательность при восстановлении данных. Когда система применяет изменения из журнала к постоянному хранилищу, она фиксирует последний использованный LSN. В случае сбоя или перезапуска системы, она может использовать этот LSN для определения, с какой точки в журнале предзаписи начать восстановление. Это обеспечивает надежность и целостность данных, а также эффективное управление изменениями в системе.
        Запись в журнале предзаписи (WAL) в PostgreSQL содержит различные метаданные и информацию о событии или изменении, которое произошло в базе данных. Точное содержание записи зависит от типа операции, которая была зафиксирована.

Элементы, включаемые в запись журнала предзаписи:

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

Сжатие WAL-файлов с помощью алгоритмов lz4 и zstd

Сжатие WAL-файлов с использованием алгоритмов lz4 и zstd реализовано во всех версиях Tantor, как и в классическом PostgreSQL.

WAL (Write-Ahead Logging) файлы используются в системах управления базами данных для обеспечения целостности данных. Сжатие WAL-файлов может помочь уменьшить использование дискового пространства и улучшить производительность. Современные алгоритмы компрессии стали предлагать гораздо лучшее сжатие при меньшем количестве тактов процессора. Lz4 хороший тому пример. Параметр wal_compression может принимать значения pglz, lz4, и zstd, наряду со стандартными on и off, которые оставили в целях обратной совместимости, такие как on, true, yes и 1 эквивалентны «pglz».


Контрольная точка

Принцип работы

Изменённые (грязные) страницы могут долгое время находиться в буферном кэше, много раз меняться и не записываться на их исходные места в файлах.

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

Переполнение диска из-за недостатка места также может привести к остановке экземпляра.

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

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

Таким образом, фоновый процесс контрольной точки не только обеспечивает целостность данных, но и оптимизирует использование дискового пространства. Этот механизм является важной частью обеспечения надежности и эффективности работы PostgreSQL.

Интервал запуска фонового процесса контрольной точки в PostgreSQL устанавливается в конфигурационных файлах базы данных. Параметр, отвечающий за этот интервал, называется checkpoint_timeout. Этот параметр определяет время (в секундах), через которое процесс контрольной точки должен быть запущен повторно.

Например, если в конфигурации установлено значение checkpoint_timeout = 15min, то процесс контрольной точки будет запускаться каждые 15 минут.

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

Подводим итоги.

Буферный кэш, как элемент архитектуры PostgreSQL, играет важную роль в повышении производительности системы. Его задача - временное хранение данных в оперативной памяти, что существенно ускоряет доступ к часто используемым данным.

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

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

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

Следующий шаг - применение журнала предзаписи (WAL). Записи в журнале используются для восстановления изменений, произошедших после последней контрольной точки. Это позволяет системе вернуть базу данных к консистентному состоянию.

Далее, после восстановления из журнала предзаписи, система синхронизирует данные в оперативной памяти с данными на диске. Этот этап важен для обеспечения полной целостности данных и избежания несогласованности между различными хранилищами.

Наконец, для оптимизации производительности и управления дисковым пространством, система запускает фоновый процесс контрольной точки. Этот процесс регулирует интервалы сохранения контрольных точек и управляет использованием дискового пространства для эффективного функционирования PostgreSQL.

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


Многоверсионность

Кортежи

Определение

В PostgreSQL кортеж (tuple) означает запись в таблице базы данных. Каждая строка в таблице представляет собой кортеж, который содержит данные, соответствующие столбцам этой таблицы. Каждое поле кортежа соответствует определенному столбцу, а сам кортеж представляет собой упорядоченный набор значений.

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

В контексте многоверсионного подхода в базах данных, такого как подход MVCC (Multi-Version Concurrency Control), кортеж может также относиться к версии строки данных в таблице, которая сохраняет историческую информацию о изменениях. Этот подход позволяет одновременно поддерживать несколько версий данных, что полезно для обеспечения консистентности данных в среде с параллельным доступом и транзакциями.

В PostgreSQL, например, MVCC используется для управления параллельным доступом к данным. Каждая транзакция видит свою собственную «версию» данных, что предотвращает конфликты и блокировки. Каждый кортеж в таблице имеет свою собственную историю изменений, и транзакции могут работать с разными версиями данных одновременно.

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


Заголовок версии строки

В PostgreSQL версия строки данных содержит заголовок, который обычно включает в себя информацию о версии, видимости и флагах состояния строки. Этот заголовок представляет собой метаданные, необходимые для управления многоверсионным подходом.

Вот основные элементы, которые могут находиться в заголовке версии строки:

Элементы вместе обеспечивают систему управления версиями в PostgreSQL возможностью поддерживать одновременное выполнение транзакций без блокировок, что является ключевым преимуществом многоверсионного подхода (MVCC). В результате при параллельном доступе к данным каждая транзакция видит свою собственную версию данных, и система может управлять конфликтами и поддерживать целостность данных.

Transaction ID (XID) в PostgreSQL - уникальный идентификатор транзакции в системе управления базой данных. Каждая транзакция в PostgreSQL получает свой собственный уникальный номер XID, который идентифицирует ее в контексте базы данных.

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

Важно отметить, что в PostgreSQL XID является 32-битным числом, и после достижения максимального значения происходит «обновление» (wraparound). Это может привести к ситуации, называемой «переполнением XID», которая требует выполнения операции очистки (VACUUM) для корректного функционирования базы данных.

В СУБД Tantor (кроме «BE») счетчик транзакций является 64-битным, что исключает переполнение.


Механизм

Вставка

Чтобы вставить данные в таблицу PostgreSQL, вам потребуется использовать оператор INSERT INTO. Давайте предположим, у вас есть таблица с именем «example_table» с колонками col1, col2, col3.

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

INSERT INTO example (col1, col2, col3) VALUES

    ('значение1', 'значение2', 'значение3');

Предположим что текущий номер транзакции будет 500, тогда в заголовке версии строки будет xmin=500, xmax=0, а указатель будет показывать на ту же саму строку. Пока никаких версий нет.

ctid в PostgreSQL представляет собой системный столбец, который указывает на физическое местоположение строки в блоке таблицы.

Он состоит из двух чисел: (block_number, index_in_block), где block_number - номер блока, а index_in_block - относительный индекс строки в этом блоке.

Если ctid имеет значение (0,1), это означает, что соответствующая строка находится в блоке с номером 0, а её относительный индекс в этом блоке равен 1.

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

Обновление

Для обновления строки в PostgreSQL используется оператор UPDATE. Пример обновления строки в таблице:

UPDATE example

SET col1 = 'значение11', column2 = 'значение22', column3 = 'значение33';

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

В контексте баз данных, термин «bloat» (раздутие) обычно означает избыточное использование дискового пространства или другие виды избыточности, что может происходить в результате долгосрочного использования базы данных. Раздувание может привести к неэффективности использования ресурсов, таких как дисковое пространство и память, а также снизить производительность системы.

В PostgreSQL «bloat» может проявляться в различных аспектах:

Пространственное раздутие (Space bloat) - когда строки удаляются или обновляются, не освобождается физическое дисковое пространство, происходит пространственное раздутие.

Индексное раздутие (Index bloat) - если индексы не регулярно перестраиваются, они также могут увеличиваться в размерах. Может привести к увеличению размера индекса и ухудшению производительности запросов.

Удаление

Чтобы удалить строку из таблицы в PostgreSQL, используйте оператор DELETE.

Пример:

DELETE FROM your_table

WHERE col3=&rsquo;значение33&rsquo;;

Для борьбы с «bloat» в PostgreSQL могут использоваться различные методы, такие как регулярная очистка (VACUUM), анализ и оптимизация индексов, а также обновление статистики. Однако важно проводить эти операции с осторожностью и, при необходимости, подходить к оптимизации базы данных с учетом конкретных требований и характеристик системы.

Эти и другие моменты будут постепенно будут раскрыты в курсе.
Но остается вопрос, а какую конкретно версию строки видит транзакция? Чтобы разобраться в вопросе, давайте поймем что такое снимок данных.


Снимок данных

Определение

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

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

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

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

Таким образом, снимок данных формируется на основе нескольких значений, зафиксированных в момент его создания:

Пример

Посмотрим, какую версию строки видит команда в снимках данных: 


Уровни изоляции

Определение

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

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

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

Read Commited

PostgreSQL не поддерживает уровень READ UNCOMMITTED (Чтение неподтвержденных данных) он совпадает с уровнем READ COMMITTED (Чтение подтвержденных данных). Можно указать только ради совместимости со стандартом.

В уровне изоляции «READ COMMITTED» в PostgreSQL, фантомные чтения представляют собой ситуации, когда транзакция видит изменения в наборе данных, которые были выполнены другой транзакцией после начала текущей транзакции. Это происходит из-за того, что «READ COMMITTED» позволяет видеть только подтвержденные (зафиксированные) изменения.

Вот пример сценария фантомного чтения на уровне «READ COMMITTED»:

Таким образом, фантомные строки могут появиться в результате выполнения запроса в середине транзакции из-за изменений, внесенных другими транзакциями. Хотя уровень «READ COMMITTED» предотвращает чтение «грязных» данных, он не исключает фантомные чтения.

Обратите внимание, что уровень «SERIALIZABLE» обеспечивает более строгую изоляцию, предотвращая и фантомные чтения, и другие аномалии, за счет полного последовательного выполнения транзакций.

На этом уровне, каждый оператор работает со своим снимком данных, поэтому на уровне изоляции «READ COMMITTED» в PostgreSQL могут возникнуть следующие аномалии:

Например, транзакция A начинает чтение данных, транзакция B добавляет новую строку, и транзакция A видит эту новую строку при последующем чтении.

Например, транзакция A читает значение из строки, транзакция B изменяет это значение, и транзакция A, читая ту же строку снова, видит измененное значение и др.

Repeatable Read

REPEATABLE READ (Повторяемое чтение):

Гарантирует, что все строки, считанные в рамках транзакции, останутся неизменными до завершения транзакции.

Предотвращает чтение «грязных» данных и фантомное чтение, но может допускать неповторяющееся чтение (non-repeatable read) и возможны аномалии сериализации

На уровне изоляции REPEATABLE READ в PostgreSQL фантомные чтения (Phantom Reads) и неповторяющиеся чтения (Non-Repeatable Reads) действительно предотвращаются. Транзакции на уровне REPEATABLE READ видят стабильный снимок данных на момент их начала, и изменения, произведенные другими транзакциями после начала текущей транзакции, не должны быть видны.

В контексте PostgreSQL это значит что снимок данных делается при выполнении первого оператора транзакции и все остальные операторы пользуются одним снимком

Serialazible

SERIALIZABLE (Сериализуемое выполнение) предоставляет самую высокую степень изоляции.

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

Предотвращает чтение «грязных» данных, фантомное чтение и неповторяющееся чтение.

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

Уровень изоляции SERIALIZABLE в PostgreSQL обеспечивает самый высокий уровень изоляции между транзакциями, гарантируя, что выполнение транзакций будет таким, как если бы они выполнялись последовательно, без взаимодействия друг с другом. Одним из механизмов, используемых для достижения этой изоляции, являются предикатные блокировки.

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


Фиксация и откат транзакции

CLOG

При фиксации или отмене транзакции, серверный процесс помимо формирования журнальной записи, устанавливает один из двух битов (как признак фиксации или отката) в разделяемой структуре памяти, называемой «Commit Log».

CLOG (Commit Log) - это буфер, который используется для отслеживания информации о фиксации (commit) транзакций. Этот механизм необходим для поддержки многоверсионности (MVCC - Multi-Version Concurrency Control) в PostgreSQL.

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

CLOG сохраняет информацию о том, была ли транзакция зафиксирована (commit) или отменена (abort).

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

Кроме CLOG, в PostgreSQL также используются другие буферы для поддержки MVCC, такие как Transaction ID (XID) и MultiXact.

Эти механизмы совместно обеспечивают надежную и эффективную поддержку работы с транзакциями и версионностью данных.

CLOG (Commit Log) в PostgreSQL состоит из набора сегментов, которые являются файлами фиксированного размера. Каждый сегмент CLOG содержит массив битов, где каждый бит представляет собой состояние фиксации транзакции. Таким образом, каждый бит в CLOG соответствует отдельной транзакции.

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

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

Фиксация

В PostgreSQL фиксация транзакции (commit) осуществляется следующим образом:

В случае отмены транзакции (ROLLBACK), вместо фиксации в CLOG записывается информация об отмене транзакции. Это также фиксируется в WAL, чтобы обеспечить целостность данных.

Этот процесс обеспечивает согласованность данных и поддерживает многоверсионность в PostgreSQL.

Откат

Когда транзакция отменяется (ROLLBACK) в PostgreSQL, соответствующая информация записывается в CLOG (Commit Log).

Изучим как происходит откат транзакции в CLOG.

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

Этот процесс обеспечивает согласованность данных в базе данных PostgreSQL при отмене транзакции.

Откат и фиксация транзакции происходит одинаково быстро - это всего лишь установка соответствующего бита в буфере CLOG.

Блокировки объектов

Очередь

В контексте PostgreSQL «честная очередь блокировок» на уровне объектов означает, что когда несколько транзакций пытаются получить блокировку на один и тот же объект данных, СУБД PostgreSQL управляет этими блокировками в справедливой очереди.

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

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

Механизм гарантирует согласованность данных, предотвращает конфликты и обеспечивает безопасность транзакций в среде с параллельным доступом к данным.

Таблица совместимости

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

СУБД «Tantor» предоставляет различные режимы блокировки для контроля параллельного доступа к данным в таблицах. Эти режимы могут использоваться для блокировки, контролируемой приложением, в ситуациях, когда MVCC не дает желаемого поведения. Кроме того, большинство команд «Tantor SE» автоматически получают блокировки соответствующих режимов, чтобы гарантировать, что ссылочные таблицы не будут удалены или изменены несовместимым образом во время выполнения команды.

Например, TRUNCATE не может быть безопасно выполнена одновременно с другими операциями на той же таблице, поэтому она получает блокировку ACCESS EXCLUSIVE на таблицу для обеспечения этого.

13.3.1. Таблица-уровень блокировок

 https://docs.tantorlabs.ru/tdb/ru/15_6/se/explicit-locking.html

Пример

К примеру существует таблица А.

К ней происходит обращение в транзакции 500 с целью выборки данных SELECT. Накладывается блокировка Access Share.

Параллельно через некоторое время приходит с транзакции 503 команда Alter table (ACCESS EXCLUSIVE). Транзакция встает в очередь.

Если придет еще одна транзакция которая не совместима по уровню блокировок, например с номером 512 Update&hellip; (ROW EXCLUSIVE) она также встанет в очередь.

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

Уровень блокировок может быть совместим. К примеру если с обновлением строк придет обновление строк той же таблицы но других, эти транзакции могут делать свою работу параллельно.


Блокировка строк

Таблица совместимости

В дополнение к блокировкам на уровне таблицы, существуют блокировки на уровне строк, которые автоматически используются «Tantor SE» в следующих контекстах.

Транзакция может удерживать конфликтующие блокировки на одной и той же строке, но помимо этого, две транзакции никогда не могут удерживать конфликтующие блокировки на одной и той же строке. Блокировки на уровне строк не влияют на запросы данных; они блокируют только писателей и блокировщиков для одной и той же строки.

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

FOR UPDATE - запрашивает блокировку строк для операций обновления, предотвращая их изменение или блокировку другими транзакциями до завершения текущей транзакции. Используется при выполнении операций UPDATE, DELETE, SELECT FOR UPDATE и подобных.

FOR NO KEY UPDATE - аналогичен FOR UPDATE, но блокировка слабее, не влияя на команды SELECT FOR KEY SHARE.

FOR SHARE: запрашивает общую блокировку строк для чтения, предотвращая изменение или блокировку другими транзакциями для операций UPDATE, DELETE, SELECT FOR UPDATE и подобных.

FOR KEY SHARE - аналогичен FOR SHARE, но блокирует SELECT FOR UPDATE и не влияет на SELECT FOR NO KEY UPDATE.

Tantor SE не сохраняет информацию о измененных строках в памяти, и нет ограничений на количество заблокированных строк одновременно. Блокировка строки может вызвать запись на диск, например, SELECT FOR UPDATE изменяет строки для их пометки как заблокированные, вызывая запись на диск.

13.3.2. Блокировки на уровне строк

https://docs.tantorlabs.ru/tdb/ru/15_6/se/explicit-locking.html#ROW-LOCK-COMPATIBILITY

«Очередь»

Команды, которые только читают данные не устанавливают блокировки на уровне строк.

Транзакции, изменяющие данные, устанавливают блокировки на уровне строк.

Поскольку строки остаются заблокированными до конца транзакции или до отката (полностью или до точки сохранения), то транзакция, которая хочет получить блокировку какой-либо строки встаёт в очередь не «за строкой», а за транзакцией, которая эту строку заблокировала.

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

Пример

Признаком блокировки строки является заполнение поля xmax в заголовке версии строки.

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

Такое действие не предусмотрено - поэтому транзакция становится в очередь.

Остальные транзакции становятся в очередь за транзакцией 521.

В случае освобождения транзакции 520, транзакция 521 захватывает новую версию строки а следующая становится произвольная транзакция из «кучи» ожидающих транзакций. Можно сказать, что в очереди есть первый в очереди за получением блокировки и все остальные.

Возможность завершить сессию по заранее установленному временному тайм-ауту

Возможность завершить сессию по заранее установленному временному тайм-ауту реализована и в версиях Tantor и PostgreSQL.

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

Для установки временного тайм-аута для сессии в PostgreSQL можно использовать параметр конфигурации &lsquo;statement_timeout`. Этот параметр определяет, сколько времени запрос может выполняться, прежде чем будет автоматически прерван.

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

Возможность завершить транзакцию по заранее установленному временному тайм-ауту

Для всех версий СУБД Tantor добавлена возможность завершения транзакции по заранее установленному временному тайм-ауту.

Добавлен GUC параметр transaction_timeout, позволяющий отменить любую транзакцию, которая продолжается дольше указанного интервала времени. Ограничение применяется как к явным транзакциям (начинающимся с BEGIN), так и к неявно начатым транзакциям, соответствующим отдельному оператору. Если это значение указано без единиц измерения, оно считается в миллисекундах. Значение нуль (по умолчанию) отключает тайм-аут.

Причины создания данного патча:

  1. Существующие timeouts (а именно: statement_timeout + idle_session_timeout) не защищают от транзакций, состоящих из серии недолгих команд и коротких пауз между ними. Если происходит такое поведение (например, длинная серия быстрых UPDATE в цикле), то это может быть опасно, поскольку напрямую влияет на общее состояние БД (проблемы с раздуванием).
  2. Администраторы баз данных могут свести к минимуму случаи длинных транзакций, устанавливая лимиты транзакций глобально, а также позволяя устанавливать их локально для определенных сеансов или для некоторых пользователей в редких случаях

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


Регламентные работы

Задачи очистки

Bloat - разрастание таблиц

Bloat (исторические данные), или разрастание таблиц, происходит из-за специфики работы MVCC. Когда в PostgreSQL вносятся изменения в строки таблицы, старые версии строк сохраняются, чтобы обеспечить консистентность и изоляцию транзакций. Эти старые версии могут создавать дополнительный объем данных, что приводит к разрастанию таблицы.

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

Периодически нужно очищать исторические данные - еще одно название dead tuple.

Очистка строк

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

Задачу можно условно назвать «фазой один», включающей следующие подзадачи:

1. Удаление исторических данных - подзадача включает в себя активное удаление устаревших версий строк из базы данных, что важно для освобождения пространства и предотвращения накопления «мусора», который может привести к разрастанию таблицы.

2. Обновление карты свободного пространства - после удаления исторических данных необходимо обновить карту свободного пространства в базе данных, что позволяет эффективнее управлять доступным пространством и предотвращает фрагментацию данных.

3. Обновление карты видимости - обработанная страница данных таблицы становится «видимой», то есть в случае неизменности данных, ее можно в следующей итерации очистки не обрабатывать.

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

Анализ

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

Вторая фаза, пересборка статистики, позволяет PostgreSQL собрать новые данные о распределении значений в оставшихся данных. Это обеспечивает оптимизатору актуальную информацию для принятия более точных решений при выборе метода выполнения запросов.

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

В PostgreSQL статистика таблицы включает в себя следующие основные аспекты:

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

Обычная очистка

Команда VACUUM в PostgreSQL не блокирует активности транзакций, но может влиять на параллельные запросы и доступ к данным во время выполнения.

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

Команда VACUUM в PostgreSQL используется для очистки исторических данных в базе данных. Если у вас есть таблицы с большим количеством удаленных или устаревших строк, VACUUM может помочь освободить пространство и поддерживать более эффективное использование ресурсов.

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

Также у команды есть параметры к примеру: VACUUM (ANALYZE, VERBOSE) имя_таблицы;

Где ANALYZE указывает на необходимость обновления статистики, а VERBOSE делает вывод более подробным.

Полная очистка

Обычная операция VACUUM в PostgreSQL обычно не возвращает свободное дисковое пространство операционной системе. Вместо этого, она помечает пространство, ранее занятое удаленными строками, как доступное для будущих операций внутри той же самой таблицы.

В случае полной очистки, такой как VACUUM FULL, PostgreSQL пытается вернуть свободное пространство операционной системе. Однако, как вы отметили, эта операция блокирует доступ к объекту, что может повлиять на возможность выполнения запросов к таблице в это время.

Использование VACUUM FULL следует оценивать осторожно, так как это более ресурсозатратная и блокирующая операция, и она может повлиять на производительность вашей базы данных.

Также важно отметить, что в реальных сценариях обычно не требуется регулярно выполнять VACUUM FULL. Вместо этого, можно использовать автоматический механизм AUTOVACUUM, который управляет подобными операциями в более оптимальном режиме.

При выполнении операции VACUUM FULL фактически создается новый объект (таблица) с нуля, копируются все нужные данные из старого объекта в новый, и, по завершении операции, старый объект удаляется. Этот процесс называется «переписывание» таблицы.

Процесс переписывания при VACUUM FULL позволяет эффективно восстановить пространство, которое занимает таблица на диске. Однако, так как это создает новую копию таблицы и может быть ресурсоемким, обычно не рекомендуется часто использовать VACUUM FULL в продакшен-системах, если нет явной необходимости.


Автоочистка

Схема работы

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

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

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

Пример

Настройка процесса автовакуума в PostgreSQL может включать в себя несколько параметров, которые определяют поведение этого процесса.

Вот несколько примеров настройки параметров:

autovacuum = on

autovacuum_vacuum_scale_factor = 0.2

autovacuum_vacuum_threshold= 50

autovacuum_max_workers = 3

autovacuum_analyze_scale_factor = 0.1
autovacuum_analyze_threshold = 50

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

autovacuum_naptime - параметр устанавливает минимальное время в секундах между итерациями автовакуума, может влиять на частоту запуска.

autovacuum_naptime = 1min

Процесс автовакуума проверяет статистику баз данных раз в 60 секунд и в случае превышения порогов наличия исторических данных и автоанализа производит очистку таблиц не более чем 3-мя процессами одновременно.


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

Разрастание индексов

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

В PostgreSQL, когда индекс вынужден выделять новую страницу из-за отсутствия места для вставки нового ключевого значения, это может привести к накоплению «мусора» в индексе. Такие ситуации могут возникать при частых операциях добавления, обновления и удаления данных, особенно в больших таблицах.

Проблема с «мусором» заключается в том, что эти выделенные страницы не всегда могут быть полностью освобождены и возвращены файловой системе. Вместо этого, они могут оставаться в индексе в виде свободных, но не освобожденных блоков.
        Для эффективного решения этой проблемы в PostgreSQL предусмотрена команда
VACUUM FULL, которая позволяет проводить перестройку индексов. Этот процесс становится неотъемлемой частью управления базой данных, позволяя удалить избыточные данные из индексов и восстановить их эффективность. Таким образом, внимательное внедрение стратегий по управлению историческими данными в индексах в PostgreSQL становится ключевым элементом поддержания оптимальной производительности и стабильности базы данных.

Разрастание индексов в базе данных может происходить из-за нескольких основных причин:

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-reindex.html#reindex

REINDEX

Команда REINDEX в PostgreSQL предназначена для перестройки индексов базы данных. Это может быть полезно в ситуациях, когда производительность запросов страдает из-за фрагментации индексов или возникают другие проблемы с ними. Однако важно учесть, что выполнение команды REINDEX приводит к блокировке внесения изменений в таблицу на время выполнения этой команды.

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

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

REINDEX INDEX имя_индекса;

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

REINDEX TABLE имя_таблицы;

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

REINDEX SCHEMA имя_схемы;

REINDEX DATABASE имя_базы_данных;

При использовании команды REINDEX важно выбирать оптимальное время для выполнения, чтобы минимизировать влияние на работу приложений. Рекомендуется проводить операцию в период низкой активности базы данных или внимательно планировать ее выполнение, чтобы избежать блокировок в критические моменты. Мониторинг активности с использованием pg_stat_activity поможет следить за процессом и предпринимать необходимые меры предосторожности.

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

REINDEX [ INDEX | TABLE | SCHEMA | DATABASE ] имя_объекта

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-reindex.html#reindex

REINDEX CONCURENTLY

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

Чтобы избавиться от излишнего блокирования, можно использовать опцию REINDEX CONCURRENTLY. Однако, применение этого параметра может привести к увеличенной нагрузке на процессор, память и ввод-вывод, что может замедлить другие операции в системе. Также возможно, что перестройка индекса приведет к ошибке.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-reindex.html#reindex

hypopg

Модуль hypopg - доступен в версиях Tantor SE и Tantor SE 1C:  

hypopg - это расширение PostgreSQL, добавляющее поддержку гипотетических индексов. Гипотетический или «виртуальный индекс» - это индекс, который на самом деле не существует, и следовательно, не требует ресурсов CPU или диска для его создания. Гипотетические индексы предоставляют возможность узнать будет ли СУБД использовать эти индексы или нет, не тратя ресурсы на их создание.

Гипотетический или виртуальный индекс - это индекс, который не существует. В процессе настройки выполнения запросов может возникнуть вопрос - если создать индекс с желаемыми параметрами, будет ли этот индекс использоваться планировщиком для выполнения запросов, которые оптимизируются. Создавать реальный индекс не хочется потому что он может повлиять на работу сессий приложения - замедлить команды изменяющие данные; создание индекса долгое. Расширение позволяет создать определение индексов, существующих только в текущей сессии и не влияющие на работу других сессий. Это определение (гипотетический индекс) принимается во внимание при создании плана выполнения в той сессии где он создан как существующий. При выполнении команды и при EXPLAIN (analyze) такой индекс не используется. Также в текущей сессии можно скрыть от планировщика любые индексы, в том числе существующие и посмотреть как это повлияет на формируемые планы выполнения команд.

Расширение имеет два представления в которых можно посмотреть какие индексы скрыты в текущей сессии и какие гипотетические индексы есть: hypopg_hidden_indexes  hypopg_list_indexes.

Работа с индексами осуществляется с помощью одиннадцати функций входящих в расширение. Гипотетические индексы создаются функцией hypopg_create_index('CREATE INDEX...') которой передаётся текст команды создания индекса. Скрытие от планировщика в текущей сессии любого, в том числе обычного индекса выполняется вызовом функции: hypopg_hide_index('имя_индекса'::regclass);

План выполнения просматривается обычной командой EXPLAIN.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/hypopg.html 


Заморозка

Переполнение счетчика

Переполнение счетчика транзакций и заморозка версий строк в PostgreSQL связаны через использование многоверсионности (MVCC).

MVCC в PostgreSQL предполагает создание различных версий строки для разных транзакций. Это позволяет транзакциям работать параллельно, избегая блокировок на чтение данных. Каждая транзакция видит свою собственную «замороженную» версию данных на момент ее начала.

Счетчик транзакций (Transaction ID, XID) используется для отслеживания порядка транзакций и определения того, какие версии строк могут быть видны для каждой транзакции. В PostgreSQL счетчик транзакций реализован как 32-битное значение (в более поздних версиях PostgreSQL существуют механизмы для обработки переполнения, но об этом мы говорили ранее).

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

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

Заморозка версий строк (Freeze): В этой фазе VACUUM замораживает версии строк, устаревшие для транзакций с самыми высокими идентификаторами транзакций (XID). Таким образом, старые версии строк фактически «замораживаются» и могут быть использованы повторно. Это помогает предотвратить переполнение счетчика транзакций и обеспечивает более эффективное использование пространства.

Для 32-битного счетчика транзакций (XID) в PostgreSQL максимальное значение равно 4,294,967,295. Когда этот предел достигается, происходит переполнение, что может привести к проблемам согласованности данных, таким как несовместимость транзакций и ошибки при попытке доступа к данным.

В более современных версиях PostgreSQL, таких как Tantor SE и других, используется 64-битный счетчик транзакций. Это увеличивает максимальное значение счетчика транзакций значительно, предотвращая переполнение и обеспечивая более долгий срок службы базы данных при высокой активности транзакций.

64-битный счетчик транзакций

Поговорим об изменениях в ядре и производительности СУБД:

В редакциях «Tantor SE» и «Tantor SE 1C» внесены улучшения, направленные на повышение производительности СУБД, в частности, внедрен 64-битный счетчик транзакций.

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

Благодаря этому системе требуется меньше времени на «заморозку» данных, что позволяет улучшить общую производительность базы данных.  С уменьшением необходимости в «заморозке» данных, уменьшается вероятность простоев в работе базы данных.

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

VACUUM FREEZE

В PostgreSQL можно явно вызвать третью фазу, заморозку версий строк (Freeze), командой VACUUM FREEZE. Это может быть полезно в ситуациях, когда вы хотите явно выполнить заморозку версий строк в определенный момент времени, независимо от автоматического выполнения VACUUM.

Команда VACUUM FREEZE замораживает версии строк для всех таблиц в базе данных, применяя третью фазу VACUUM ко всем устаревшим версиям строк. Это может быть полезно, например, когда вы заметили увеличение количества старых версий строк и хотите принудительно выполнить заморозку для управления счетчиком транзакций.

Применяется только в том случае, если счетчик транзакций 32-битный. Tantor SE использует 64 битный счетчик транзакций. В заморозке в таком случае нет необходимости.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/differences.html

pg_cron

Модуль pg_cron - также доступен во всех версиях «Tantor».

pg_cron - это расширение, которое позволяет запускать периодические задания напрямую в базе данных, используя синтаксис, подобный cron в Unix.

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

Основные возможности pg_cron:

pg_qualstats

Модуль pg_qualstats - доступен в версии «Tantor SE».

Сохраняет статистические данные по найденным предикатам в операторах WHERE и предложениях JOIN.

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

pg_qualstats собирает статистику по следующим аспектам:


Выполнение запросов

Общие сведения

SQL - декларативный язык

SQL (Structured Query Language) - это декларативный язык программирования, вам нужно описать, что вы хотите достичь, а не указывать, как это сделать шаг за шагом. В отличие от императивных языков программирования, где программа предоставляет последовательность операторов, которые выполняются по порядку, декларативные языки, такие как SQL, фокусируются на том, что должно быть достигнуто, оставляя оптимизацию и реализацию деталей исполнения системе управления базами данных.

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

Когда пользователь отправляет запрос SQL системе управления базами данных (СУБД) PostgreSQL, происходит следующий общий процесс:


Парсинг

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

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

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

В случае SQL-запроса этот процесс гарантирует, что пользовательский запрос соответствует синтаксическим правилам SQL, что позволяет системе правильно интерпретировать и выполнить запрос.

Семантический разбор в контексте SQL:

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

Трансформация запроса

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

Давайте рассмотрим более подробно, что происходит на этом этапе. Преобразование во внутреннюю структуру - СУБД принимает текст SQL-запроса, который представляет собой высокоуровневое описание того, что требуется получить или выполнить.

Текст разбирается и превращается во внутреннюю структуру данных, также называемую деревом запроса или деревом выражения. Это дерево представляет собой иерархическую структуру, которая отражает логическую структуру запроса.


Планирование

Задача планирования

Этап планирования запроса в процессе выполнения SQL-запроса в СУБД представляет собой процесс, в ходе которого оптимизатор запросов принимает решения о наилучшем способе выполнения запроса.

Давайте подробнее разберем этот этап:

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


Выполнение

Фаза выполнения запроса

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

Давайте более подробно рассмотрим этот этап:

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


Чтение плана запроса

EXPLAIN

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

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

EXPLAIN (analyze)

SELECT col1, col2 FROM v_table WHERE name='test1'::text ;

                              QUERY PLAN                                          

----------------------------------------------------------------------

 Seq Scan on test  (cost=0.00..25.00 rows=6 width=8) (actual time=0.687..0.691 rows=1 loops=1)

   Filter: (name = 'test1'::text)

   Rows Removed by Filter: 1

 Planning Time: 0.121 ms

 Execution Time: 0.875 ms

(5 rows)

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

Примечание: важно помнить, что команда EXPLAIN не фактически выполняет запрос, а лишь анализирует план выполнения. Вы можете использовать EXPLAIN ANALYZE, чтобы выполнить запрос и получить подробную статистику по его выполнению. Однако, выполнение EXPLAIN ANALYZE может занять больше времени, чем просто EXPLAIN, так как она фактически выполняет запрос.

Извлечение информации

В PostgreSQL существуют три основных способа доступа к данным (в контексте плана выполнения запроса):

Seq Scan on your_table

Index Scan using your_index on your_table

Bitmap Index Scan on your_table

Каждый из этих способов имеет свои преимущества и недостатки, и оптимизатор запросов PostgreSQL выберет подходящий метод в зависимости от структуры таблицы, условий запроса и других факторов.

Объединение источников

После извлечения информации из таблиц, происходит объединение источников информации.

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

Nested Loop Join

Hash Join

Merge Join

Выбор конкретного метода зависит от размера таблиц, наличия индексов, структуры данных и других факторов.

Оптимизатор запросов PostgreSQL будет выбирать наиболее подходящий метод на основе статистики и текущих условий.

Объединяются всегда по две пары.

Удаление ненужных соединений (join), при соединении таблицы с самой собой

Для версии SE 1C доступно удаление ненужных соединений (join) при соединении таблицы с самой собой.

Данное изменение реализует удаление самоприсоединения (Self Join Removal, SJR), что в некоторых сценариях улучшает производительность запросов по нескольким причинам:

1. Уменьшение объема обрабатываемых данных. Самоприсоединение, как правило, увеличивает количество данных, которые необходимо обрабатывать при выполнении запроса. Заменой самоприсоединения на сканирование таблицы мы можем сократить объем обрабатываемых данных, что ускоряет выполнение запроса.

2. Уменьшение сложности запроса. Присоединение таблицы к себе может увеличить сложность запроса, что замедляет его выполнение. Удаление самоприсоединения приводит к упрощению запроса, что помогает ускорить его выполнение.

3. Уменьшение нагрузки на систему. Присоединение таблицы к себе может потребовать больше системных ресурсов, таких как процессорное время и память. Удаление самоприсоединения может помочь снизить нагрузку на систему, особенно при обработке больших объемов данных.

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

Сортировка

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

Некоторые из них включают:

Sort Method: quicksort Memory: 25kB

Sort Method: external merge  Disk: 2304kB

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

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

SELECT column1, column2 FROM your_table ORDER BY column1 ASC;

SELECT DISTINCT column1 FROM your_table ORDER BY column1;

«Sort Method: top-N heapsort» в плане выполнения запроса указывает на то, что используется алгоритм сортировки «top-N heapsort» для получения первых N строк результата запроса.

Группировка

GroupAggregate - этот узел отображает использование группировки и агрегации в запросе.

GroupAggregate (cost=1000.00..1200.00 rows=100 width=12)

HashAggregate - этот узел отображает использование хеширования при выполнении группировки и агрегации.

HashAggregate (cost=1000.00..1200.00 rows=100 width=12) Hash Key: department

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

Установки EXPLAIN

Команда отображает план выполнения, который генерирует планировщик Tantor SE для предоставленного выражения.

Самые распространенные и часто используемые опции для команды EXPLAIN в PostgreSQL включают:

Эти опции предоставляют дополнительную информацию, которая может быть полезна при понимании и оптимизации выполнения запросов в PostgreSQL.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-explain.html#explain


Оценка

Кардинальность

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

Типичные значения кардинальности включают:

Оценочная кардинальность (Estimated Cardinality) - это предварительное ожидание оптимизатора запросов по количеству возвращаемых строк для каждой операции в плане. Она часто видна в оценках строк (rows) в выводе команды EXPLAIN. Например, rows=100 может означать, что ожидается 100 строк.

Фактическая кардинальность (Actual Cardinality) - представляет собой реальное количество строк, возвращенных каждой операцией в плане после выполнения запроса. Она может быть видна в статистике выполнения, когда используется опция ANALYZE в команде EXPLAIN.

Кардинальность в плане выполнения запроса важна для анализа и оптимизации запросов.

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

Селективность

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

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

В контексте плана выполнения запроса в PostgreSQL, селективность может быть видна в статистике оценки (estimates) для каждой операции в плане. Например, оценка числа возвращаемых строк и оценка фильтрации по условиям запроса. Эти оценки могут помочь оптимизатору запросов выбирать наилучшие планы выполнения в зависимости от селективности условий.

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

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

К примеру, в таблице 100 строк возвращается 5 значит мы говорим о высокой селективности, 5%, если же селективность приближается к 100% это низкая селективность.

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

Стоимость запроса

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

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

В примере, cost=0.00..18.00 - это оценка стоимости для операции Seq Scan. Общая оценка стоимости для всего плана выполнения может быть видна в корневой строке вывода команды EXPLAIN.

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


Статистика

Источники статистики

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

Основные источники статистики, которые оптимизатор запросов может использовать:

pg_statistic (pg_stats)

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

В таблице pg_statistic содержатся следующие статистические данные для каждого столбца.  К примеру посмотрим какое количество NULL есть в третьем столбце таблицы

SELECT stanullfrac  FROM pg_statistic WHERE starelid = 'test'::regclass AND staattnum = 3;  

stanullfrac  

-------------

  0.9981884

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

Более подробно в документации

https://docs.tantorlabs.ru/tdb/ru/15_6/se/catalog-pg-statistic.html#pg-statistic

pg_state_statements

pg_stat_statements - расширение предоставляющее статистику об использовании SQL-запросов в базе данных. Оно отслеживает различные метрики, такие как общее количество выполненных запросов, время выполнения запросов, количество строк, затронутых каждым запросом, а также другие характеристики. Этот модуль полезен для анализа производительности и оптимизации запросов в приложении.

Вот несколько сценариев, когда pg_stat_statements может быть полезен:

Анализ производительности - модуль pg_stat_statements позволяет администраторам баз данных и разработчикам получить общее представление о том, какие запросы чаще всего выполняются, каково их среднее время выполнения и какие запросы занимают больше всего ресурсов.

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

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

Мониторинг изменений - pg_stat_statements позволяет отслеживать изменения в производительности запросов с течением времени. Если какие-то запросы становятся медленнее из-за изменений в данных или индексах, это может быть замечено с помощью статистики.

Для активации pg_stat_statements в PostgreSQL, необходимо добавить или раскомментировать соответствующие строки в файле конфигурации PostgreSQL (postgresql.conf) и перезапустить сервер. После этого можно использовать предоставляемые представления, такие как pg_stat_statements, для анализа статистики запросов.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/pgstatstatements.html#f-48-pg-stat-statements

pg_store_plans

Расширение pg_store_plans предоставляет средства для мониторинга и сбора статистики по выполнению планов SQL-запросов, обрабатываемых сервером PostgreSQL.

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

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/pg_store_plans.html#f-50-pg-store-plans

online_analyze

Модуль online_analyze, также реализован в версии «1С».

Делает вызов анализа сразу после INSERT/UPDATE/DELETE/SELECT INTO для затронутых таблиц. Включается при указании параметра online_analyze.enable = on в postgresql.conf. Этот модуль необходим для поддержки 1С.

plantuner

Модуль plantuner доступен в версии «Tantor SE 1С».

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

Есть много ситуаций, когда разработчик хочет временно отключить определенные индексы, не удаляя их, или дать инструкцию планировщику использовать определенный индекс. Если переменная GUC plantuner.fix_empty_table установлена в true, то модуль устанавливает в ноль количество страниц/кортежей таблицы, которая не имеет блоков в файле.

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

pg_hint_plan

Модуль pg_hint_plan - Доступен в версиях «SE» и «SE 1С».

Позволяет настраивать планы выполнения SQL запросов, используя так называемые «подсказки» в комментариях SQL, тем самым давая возможность компенсировать ошибки планировщика возникающие при крайних ситуациях.

Читает фразы-подсказки в комментарии специальной формы, данные с целевым оператором SQL.

Специальная форма начинается с `"/\*+"` и заканчивается `"\*/"`.

Фразы-подсказки состоят из имени подсказки и следующих параметров, заключенных в круглые скобки и разделенных пробелами. Каждая фраза-подсказка может быть разделена новыми строками для удобства чтения.


Расширяемость

Механизм использования

Историческая справка

Расширяемость (extensibility) в контексте PostgreSQL означает способность системы быть легко расширяемой и адаптируемой под различные потребности пользователя. PostgreSQL предоставляет механизмы для добавления новых функциональностей, типов данных, языков программирования, иных расширений и модулей. Расширяемость является важным аспектом для того, чтобы база данных могла эффективно справляться с разнообразными задачами и требованиями различных приложений.

Исторически, PostgreSQL активно разрабатывалась с упором на расширяемость. В ранних версиях PostgreSQL, еще когда она называлась POSTGRES, создатель системы Майкл Стоунбрейкер (Michael Stonebraker) и его команда уделяли внимание расширяемости, предоставляя пользователю гибкость в определении новых типов данных, функций, и внешних языков программирования.

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

Её расширяемость проявляется в следующих аспектах:

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

Где хранятся?

Утилита pg_config в PostgreSQL предоставляет информацию о конфигурации вашей установки PostgreSQL и позволяет узнать директорию, где хранятся расширения.

postgres@education:~$ pg_config --sharedir

/opt/tantor/db/14/share/postgresql

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

postgres=# SELECT setting FROM pg_config()  

WHERE name = 'SHAREDIR';

             setting                

------------------------------------

/opt/tantor/db/16/share/postgresql

(1 row)

Управление расширениями

Расширение в PostgreSQL является механизм модификации системного каталога конкретной базы данных с которой идет работа в сессии, потому что вносит изменения в саму базу данных, расширяя её функциональность. Расширение может добавлять новые типы данных, функции, операторы, агрегатные функции и другие объекты базы данных.

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

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

В PostgreSQL существует несколько команд для управления расширениями:

Пример: CREATE EXTENSION my_extension;

В этой команде my_extension - это имя устанавливаемого расширения. Если у расширения есть зависимости, PostgreSQL автоматически установит их.

Пример: ALTER EXTENSION my_extension UPDATE TO '1.1';

В этой команде my_extension - это имя установленного расширения, и '1.1' - это целевая версия. Эта команда также может использоваться для других операций с расширением, таких как добавление или удаление файла управления.

DROP EXTENSION my_extension;

В этой команде my_extension - это имя устанавливаемого расширения. При удалении расширения также будут удалены связанные с ним объекты базы данных.

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

Кроме того, для просмотра информации о текущих расширениях в базе данных, вы можете использовать запрос к каталогу pg_available_extensions или pg_extension.

Более подробно https://docs.tantorlabs.ru/tdb/ru/15_6/se/extend.html

Необходимые файлы

Для установки расширения минимально требуется

Управляющий файл имя_расширения.control. Этот файл содержит метаданные о расширении и имеет структуру аналогичную файлу postgresql.conf.

Файл с объектами расширения имя_расширения&ndash;1.0.sql (где 1.0 - версия расширения). Этот файл содержит SQL-код для создания объектов базы данных, необходимых для работы расширения. Это могут быть функции, таблицы, типы данных и другие объекты.

Эти два файла являются минимальным набором для установки расширения. Управляющий файл содержит метаданные о расширении, а файл с объектами расширения содержит SQL-код для создания необходимых объектов базы данных, таких как функции, таблицы и т.д.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/extend-extensions.html#id-1.8.3.19.11

Содержимое управляющего файла

Содержимое управляющего файла расширения (например, foo.control) должно включать минимально необходимые метаданные для правильной установки и работы расширения.

Вот пример простого управляющего файла:

# расширение foo

comment = 'Пример расширения'

default_version = '1.0'

module_pathname = '$libdir/имя_расширения'

relocatable = true

schema = public

#requires = ''

Разберем, что означает каждый параметр:

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

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/extend-extensions.html#id-1.8.3.19.11 

Содержимое скрипта

Вот пример файла SQL для расширения "foo", где первая строка содержит подсказку для пользователя:

\echo Use "CREATE EXTENSION foo" to load this file. \quit

-- foo--1.0.sql

CREATE OR REPLACE FUNCTION foo_function() RETURNS text AS $$

BEGIN

  RETURN 'Hello, foo!';

END;

$$ LANGUAGE plpgsql;

CREATE TABLE foo_table (

  id serial PRIMARY KEY,

  name text

);

Этот файл содержит комментарий с помощью \echo, который предоставляет подсказку пользователю о том, как использовать данный файл. При помощи \quit завершается выполнение файла после его выполнения. Затем следует SQL-код для создания функции и таблицы в расширении "foo". В код может включаться также любые команды изменяющие объекты и т.д.


Обновление

Обновление версии

Процедура обновления расширения в PostgreSQL может включать выполнение SQL-скриптов для применения изменений между старой и новой версиями.

Вот более подробный второй пункт:

Применение SQL-скриптов для обновления до текущей версии:

Если изменения расширения требуют применения дополнительных SQL-скриптов, вы можете использовать команду ALTER EXTENSION ... UPDATE. Эта команда выполняет все необходимые SQL-скрипты, связанные с обновлением версии расширения до текущей версии.

ALTER EXTENSION foo UPDATE;

После выполнения этой команды PostgreSQL найдет и применит все SQL-скрипты, начиная с текущей версии и до новой версии расширения.

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

ALTER EXTENSION foo UPDATE TO '1.1';

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/extend-extensions.html#id-1.8.3.19.14 

Пути обновления

«Пути обновления расширения» (extension update paths) в PostgreSQL представляют собой набор версий расширения и связанных с ними SQL-скриптов обновления, которые позволяют перейти от одной версии расширения к другой. Эти пути обновления обеспечивают механизм для безопасного и последовательного обновления расширения в базе данных.

Для просмотра доступных путей обновления расширения в PostgreSQL можно воспользоваться системной функцией pg_available_extension_versions. Эта функция возвращает информацию о доступных версиях расширений и их путях обновления.

SELECT name, version FROM pg_available_extension_versions WHERE name = 'foo';

  name    | version  

-----------+---------

foo                | 1.0

foo                | 1.1

foo                | 1.2

(3 rows)

Этот запрос вернет информацию о версиях расширения "foo" и их путях обновления, если такие пути определены. Обратите внимание, что не все расширения могут иметь явно определенные пути обновления.

Функция pg_extension_update_paths позволяет посмотреть возможные пути обновления для расширения.

SELECT * FROM pg_extension_update_paths('foo');

Этот запрос вернет информацию о всех путях обновления для расширения "foo", включая те, которые не являются прямыми.

  source | target |    path        

---------+---------+-----------------

 1.0     | 1.1     | 1.0--1.1

 1.0     | 1.2     | 1.0--1.2

На примере видно, что с версии 1.1 до версии 1.2 напрямую обновится нельзя. Нужно будет сначала удалить версию 1.1 а потом поставить версию 1.2


FDW

Внешние источники информации

FDW в PostgreSQL означает «Foreign Data Wrapper» (Обертка для внешних данных). Это механизм, который позволяет PostgreSQL взаимодействовать с данными, которые хранятся вне самой базы данных PostgreSQL, например, в других базах данных, файлах CSV, веб-службах и т. д. FDW позволяет PostgreSQL создавать виртуальные таблицы, которые отображают данные из внешних источников, как если бы они были обычными таблицами в PostgreSQL.

Написание внешней обертки данных:  

https://docs.tantorlabs.ru/tdb/ru/15_6/se/fdwhandler.html

Гетерогенные среды

В PostgreSQL существует несколько различных FDW, включая:

Также существуют обертки внешних данных сторонние:

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

Извлечение информации из файла

file_fdw - позволяет PostgreSQL создавать виртуальные таблицы на основе данных, хранящихся в файлах различных форматов, таких как CSV.

Этот FDW предоставляет возможность создавать виртуальные таблицы на основе данных, хранящихся в файлах различных форматов, таких как CSV. Вы можете использовать его для чтения данных из CSV-файлов и представления их как таблиц в PostgreSQL.

Пример использования:

CREATE EXTENSION file_fdw;

CREATE SERVER csv_server FOREIGN DATA WRAPPER file_fdw;

CREATE FOREIGN TABLE csv_table (

    column1 data_type,

    column2 data_type,

    -- ...

)

SERVER csv_server

OPTIONS (filename '/path/to/your/csv/file.csv', format 'csv');

https://docs.tantorlabs.ru/tdb/ru/15_6/se/file-fdw.html#f-19-file-fdw 


Раздел 3. Конфигурирование

Конфигурирование

Обзор

Обзор

Существует около 370 параметров конфигурации, которые влияют на работу экземпляра.

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

Параметры имеют название (нечувствительно к регистру) и значение.

Значения параметров могут быть:

Названия типов параметров не связаны с типами данных SQL. Максимальные и минимальные значения численных типов для каждого параметра указаны в столбцах min_val и max_val представления pg_settings.

Значения строковых параметров лучше заключать в апострофы. Если в самом значении присутствует апостроф, то дублировать апостроф (два апострофа).

Для численных параметров с единицами измерений допустимыми обозначениями единиц измерения являются (регистр важен):

B (байты), kB (килобайты), MB (мегабайты), GB (гигабайты) и TB (терабайты);

us (микросекунды), ms (миллисекунды), s (секунды)min (минуты), h (часы) и d (дни).

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

Для "enum" список допустимых значений можно посмотреть в столбце enumvals представления pg_settings.

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-custom.html 

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config.html 

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

При создании кластера создаются два файла:

1) основной файл с параметрами конфигурации кластера postgresql.conf 

Если кластер запущен расположение можно посмотреть в значении параметра config_file

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

Можно посмотреть параметры основного процесса: postgres --help

postgres is the PostgreSQL server.

Usage:

  postgres [OPTION]...

Options:

  -B NBUFFERS        number of shared buffers

  -c NAME=VALUE      set run-time parameter

  -C NAME            print value of run-time parameter, then exit

  -d 1-5             debugging level

  -D DATADIR         database directory

Ключом -c можно передавать любые параметры конфигурации. Пример:
pg_ctl start -o "-c config_file=/opt/postgresql.conf"

2) файл postgresql.auto.conf Он всегда находится в директории PGDATA. Если кластер запущен, расположение PGDATA можно посмотреть в значении параметра data_directory

Выносить файл postgresql.conf вне директории PGDATA может быть удобно при резервировании и восстановлении. Утилита резервирования pg_basebackup копирует только содержимое PGDATA (и табличных пространств), то параметры, специфичные для резервного узла можно поместить в postgresql.conf вне PGDATA и этот файл не будет стерт при восстановлении. Утилита pg_rewind также синхронизирует только директорию PGDATA и табличных пространств.

Просмотр параметров

Текущие значения параметров кластера можно и удобно просматривать командой psql \dconfig маска_параметра.

Например, postgres=# \dconfig *data_d*

              List of configuration parameters

      Parameter      |                 Value                

---------------------+---------------------------------------

 data_directory      | /var/lib/postgresql/tantor-se-16/data

 data_directory_mode | 0750

покажет значения параметров, в которых встречается строка data_d

Текущие значения параметров кластера можно и удобно просматривать командой psql \dconfig маска_параметра.

Например, postgres=# \dconfig *data_d*

              List of configuration parameters

      Parameter      |                 Value                

---------------------+---------------------------------------

 data_directory      | /var/lib/postgresql/tantor-se-16/data

 data_directory_mode | 0750

покажет значения параметров, в которых встречается строка data_d.

Команда SHOW покажет текущие значения параметра. Клавиша табуляции в psql покажет допустимые значения. SHOW показывает один параметр. Неудобство команды SHOW в том, что ее надо завершать &ldquo;;&rdquo; иначе она останется в буфере psql.

postgres=# show data_directory;

            data_directory            

---------------------------------------

 /var/lib/postgresql/tantor-se-16/data

(1 row)

Очистить буфер psql можно командой \r

postgres=# \r

Query buffer reset (cleared).

Функция current_setting(имя параметра) - аналог команды SHOW.

Представление pg_file_settings параметры, которые явно указаны в файлах параметров. Это представление может быть полезным для предварительного тестирования изменений в конфигурационных файлах - не допущена ли ошибка при редактировании файлов. Представление pg_file_settings не показывает текущие значения, которые использует экземпляр. Столбец applied имеет значение "f", если значение параметра: отличается от текущего и для применения значения из файла требуется перезапуск кластера.

В остальных случаях (значение не менялось или достаточно перечитать файлы) значение в столбце applied будет "t".

Представление pg_settings показывает текущие действующие значения параметров. Команда SHOW ALL; аналог запроса к представлению pg_settings, но нельзя вывести только часть параметров, поэтому SHOW ALL; неудобна.

Содержимое любого файла можно посмотреть с помощью функции

SELECT pg_read_file('./postgresql.auto.conf') \g (tuples_only=on format=unaligned)

Представление pg_hba_file_rules показывает содержимое файла pg_hba.conf. Из столбца error этого представления можно узнать описание ошибки, если она допущена при редактировании файла. Файл pg_hba.conf и pg_ident.conf содержат настройки безопасности.

Файл postgresql.conf редактируется вручную.

Просмотр одного параметра на запущенном или остановленном экземпляре:

postgres -C имя_параметра
https://docs.tantorlabs.ru/tdb/ru/15_6/se/config-setting.html 


Изменение параметров конфигурации

Файл postgresql.conf

Файл postgresql.conf - основной файл, в котором хранятся параметры конфигурации кластера. Имеется около 370 параметров конфигурации плюс параметры расширений и разделяемых библиотек (*.so) загружаемых с помощью параметра конфигурации shared_preload_libraries.

Файл создается утилитой initdb из файла примеров

/opt/tantor/db/16/share/postgresql$ ls -w 1 *.sample

pg_hba.conf.sample

pg_ident.conf.sample

pg_service.conf.sample

postgresql.conf.sample

psqlrc.sample

В файлы *.sample можно внести изменения. Закомментированные строки начинаются символом #

Утилита initdb вносит изменения в часть строк в зависимости от переданных ей параметров, переменных окружения установленных перед её запуском, внутренней логики. Изменения можно посмотреть сравнив файлы

diff postgresql.conf postgresql.conf.sample

65c65

< max_connections = 100  # (change requires restart)

---

> #max_connections = 100  # (change requires restart)

Список параметров на которые реагирует postgres (а не параметры расширений и произвольные параметры приложений) можно вывести в файл postgres --describe-config > file.txt

Столбцы в файле разделены табуляцией.

Использование include и include_dir может быть полезным для компаний, предоставляющих облачные решения в виде большого числа кластеров с почти одинаковой конфигурацией для разных клиентов. Но нужно помнить о том, что параметр указанный «ниже» перекрывает параметр заданный «выше» (ближе к началу файла конфигурации).

Файл postgresql.auto.conf

Файл postgresql.auto.conf это текстовый файл, расположенный в директории PGDATA. Его можно редактировать напрямую, но нежелательно так как можно опечататься.

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

Синтаксис:

ALTER SYSTEM SET параметр { TO | = } { значение [, ...] | DEFAULT };

ALTER SYSTEM RESET параметр;

ALTER SYSTEM RESET ALL;

Изменения после этой команды, а также после редактирования любых файлов конфигурации не применяются, нужно перечитать конфигурацию или перегрузить кластер. Перегрузка кластера нужна только для применения параметров, которые не могут быть изменены динамически (без перегрузки кластера). Такие параметры можно назвать «статическими».

Только пользователи с атрибутом SUPERUSER и пользователи, которым предоставлена привилегия ALTER SYSTEM, могут изменять параметры кластера с помощью команды ALTER SYSTEM.

Команда не может выполняться в рамках транзакции.

Применение изменений параметров конфигурации

Для применения изменений (перечитывания) в текстовых файлах параметров конфигурации самое удобное использовать функцию

SELECT pg_reload_conf();

 pg_reload_conf

----------------

 t

(1 row)

Также можно использовать утилиту:

pg_ctl reload -D /var/lib/postgresql/tantor-se-16/data

server signaled

Также можно послать сигнал SIGHUP (номер 1) основному процессу.

Например, послать сигнал процессам с названием postgres (синоним «postmaster») всех запущенных кластеров:

killall -1 postgres

Параметры заданные в postgresql.auto.conf перекрывают значения параметров postgresql.conf.

Если в postgresql.conf параметр указан несколько раз, применяется указанный ближе к концу файла.

Привилегии на изменение параметров

Часть параметров конфигурации может быть изменена только ролью с атрибутом SUPERUSER.

alter user user1 superuser;

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

Выдача привилегии на изменение параметра конфигурации:

create role user1 login;

grant alter system on parameter update_process_title to user1;

Также есть привилегия на установку параметров на уровне сессии:

grant set on parameter update_process_title to user1;

Отозвать выданную привилегию можно командой

revoke alter system, set on parameter update_process_title from user1;

Посмотреть список привилегий можно командой psql:

\dconfig+ *

Привилегии будут указаны в столбце Access privileges

postgres=# \dconfig+ update_process_title

                    List of configuration parameters

      Parameter       | Value | Type |  Context  |  Access privileges   

----------------------+-------+------+-----------+----------------------

 update_process_title | off   | bool | superuser | postgres=sA/postgres+

                      |       |      |           | user1=s/postgres

Где A - право на ALER SYSTEM, s - право на SET.

Недостаток - нельзя отфильтровать по наличию привилегии. Более удобно использовать запрос select * from pg_parameter_acl; который выдаёт только те параметры, на которые были назначены привилегии

https://docs.tantorlabs.ru/tdb/ru/15_6/se/ddl-priv.html 

https://docs.tantorlabs.ru/tdb/ru/15_6/se/view-pg-settings.html 

Контекст параметров

В столбце context представления pg_context есть 7 вариантов значений.

select context, count(name) from pg_settings
where name not like '%.%' group by context order by 1;

      context      | count

-------------------+-------

 backend           |     2

 internal          |    18

 postmaster        |    64

 sighup            |    96

 superuser         |    44

 superuser-backend |     4

 user              |   143

(7 rows)

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

postmaster - для применения требуют перезапуск экземпляра кластера.

sighup - для применения достаточно перечитать файлы, например, выполнить функцию pg_reload_conf() или утилиту pg_ctl reload.

superuser - могут устанавливаться на уровне сессии, но у пользователя должен быть атрибут SUPERUSER или привилегия на изменение этого параметра.

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

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

user - можно менять в течение сессии или на уровне кластера в файлах параметров, в последнем случае перечитав файлы.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/view-pg-settings.html 


Уровни установки параметров

Параметры устанавливаются на уровнях:

Если у параметра в столбце context представления pg_settings значение не internal, то этот параметр можно поменять командой ALTER SYSTEM или отредактировав файлы параметров конфигурации.

Если у параметра в столбце context представления pg_settings значения user, backend, superuser, то значение параметра можно поменять на других уровнях:

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

ALTER DATABASE name SET parameter { TO | = } { value | DEFAULT };

ALTER DATABASE name SET parameter FROM CURRENT;

ALTER DATABASE name RESET parameter;

ALTER DATABASE name RESET ALL;

На уровне роли или роли, подсоединенной к базе данных:

ALTER ROLE .. [ IN DATABASE name ] SET parameter { TO | = } { value | DEFAULT }

ALTER ROLE .. [ IN DATABASE name ] SET parameter FROM CURRENT;

ALTER ROLE .. [ IN DATABASE name ] RESET parameter;

ALTER ROLE .. [ IN DATABASE name ] RESET ALL;

Примечание: столбец category представления pg_settings отражает название подсистемы, на которую влияет параметр, а не уровень установки. Этот столбец используется для классификации параметров.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-alterdatabase.htm 

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-alterrole.html 

На уровне транзакции значение меняется командой SET LOCAL.

Пример:

SET work_mem to '16MB'; или SELECT set_config('work_mem', '16MB', false); где false &ndash; установить на уровне сессии.

SET work_mem to DEFAULT; сбрасывает на значение, которое имел бы параметр, если бы в текущей сессии не выполнялись команды SET

RESET work_mem; то же самое что предыдущая команда

SET LOCAL work_mem to '16MB'; или SELECT set_config('work_mem', '16MB', true);

ALTER {PROCEDURE | FUNCTION} и дальше одно из перечисленного:
 SET параметр { TO | = } { значение | DEFAULT };

    SET параметр FROM CURRENT;

    RESET параметр;

    RESET ALL;

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-set.html 

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-alterprocedure.html 

Параметры хранения таблиц

На уровне таблиц и индексов есть возможность установить параметры хранения. Параметрами хранения на уровне таблиц можно переопределить параметры для автовакуума при работе с таблицей и/или её TOAST таблицей.

ALTER TABLE имя SET (параметр_хранения = значение);

ALTER TABLE имя ALTER COLUMN имя SET STATISTICS число; перекрывает значение параметра конфигурации default_statistics_target для столбца таблицы. Диапазон значений от 0 до 10000. -1 возвращает к использованию default_statistics_target.

Параметры с префиксом "toast." влияют на работу с TOAST таблицей. Если они не установлены, на TOAST действует параметры таблицы.

postgres=# alter table имя set (toast.<нажать клавишу табуляции два раза>

toast.autovacuum_enabled

toast.autovacuum_freeze_max_age

toast.autovacuum_freeze_min_age

toast.autovacuum_freeze_table_age

toast.autovacuum_multixact_freeze_max_age

toast.autovacuum_multixact_freeze_min_age

toast.autovacuum_multixact_freeze_table_age

toast.autovacuum_vacuum_cost_delay

toast.autovacuum_vacuum_cost_limit

toast.autovacuum_vacuum_insert_scale_factor

toast.autovacuum_vacuum_insert_threshold

toast.autovacuum_vacuum_scale_factor

toast.autovacuum_vacuum_threshold

toast.log_autovacuum_min_duration

toast.vacuum_index_cleanup

toast.vacuum_truncate

postgres=# alter table t set (toast.<нажать клавишу табуляции два раза>

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-createtable.html 

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-altertable.html 


Категории параметров

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

select category, count(name) from pg_settings group by category order by 2 desc;

                      category                      | count

----------------------------------------------------+-------

 Client Connection Defaults / Statement Behavior    |    31

 Developer Options                                  |    25

 Resource Usage / Memory                            |    22

 Query Tuning / Planner Method Configuration        |    22

 Reporting and Logging / What to Log                |    21

 Preset Options                                     |    18

 Write-Ahead Log / Settings                         |    15

 Connections and Authentication / SSL               |    14

 Autovacuum                                         |    13

 Query Tuning / Planner Cost Constants              |    13

 Reporting and Logging / Where to Log               |    13

 Client Connection Defaults / Locale and Formatting |    12

 Replication / Standby Servers                      |    11

...

(42 rows)

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

https://momjian.us/main/writings/pgsql/administration.pdf  (стр.21-65)

Опции для разработчиков

Категория параметров Developer Options включает в себя параметры, которые не должны использоваться в производственной базе данных. Однако некоторые из этих параметров могут быть использованы для восстановления содержимого таблиц, если в них повреждён блок и восстановление другими способами не привело к успеху (блок поврежден в физических репликах и бэкапах). Пример таких параметров:

ignore_system_indexes

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

zero_damaged_pages

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-developer.html 

Пользовательские настройки (Customized Options)

Расширения и библиотеки, подгружаемые параметром shared_preload_libraries или командой LOAD могут иметь свои параметры конфигурации. Эти параметры обрабатываются по логике обычных параметров. Однако, эти параметры неизвестны СУБД до тех пор, пока не подгрузится модуль. В частности, СУБД не может проверить допустимость значений параметров при их изменении например командой ALTER SYSTEM поэтому до загрузки библиотеки эта команда не может устанавливать неизвестные СУБД параметры, даже если в названии параметра есть точка. На уровне сессии их можно устанавливать. По умолчанию, если в названии параметра присутствует точка, СУБД считает такие параметры customized options (можно перевести как «пользовательские настройки», «внесистемные параметры»). Разработчики расширений и библиотек в качестве префикса указывают название своего расширения и придумывают названия параметров. Также можно сохранять и произвольные названия параметров, если в названии присутствует точка в postgresql.conf.

Как только библиотека подгружается (например, команда LOAD) и «регистрирует» программным вызовом свои параметры, СУБД проверяет значения параметров и если они недопустимы, то устанавливает их в значение по умолчанию которое указывает библиотека. Те параметры, которые библиотека не регистрировала при загрузке программным вызовом удаляются из памяти, как будто их не устанавливали в файле конфигурации postgresql.conf и на других уровнях. Предупреждение об этом может быть записано в журнал кластера.

Имена параметров без точки в названии должны существовать в СУБД, использование несуществующего имени параметра (например, опечатка) в файле postgresql.conf не даст запустить кластер.

waiting for server to start....
LOG:  
unrecognized configuration parameter "myappparam1" in file "/var/lib/postgresql/tantor-se-16/data/postgresql.conf" line 834

FATAL:  configuration file "/var/lib/postgresql/tantor-se-16/data/postgresql.conf" contains errors

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-custom.html 


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

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

Логическое значение - значения можно задавать, как:

 on, off, true, false, yes, no, 1, 0

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

Целое или десятичное число - если целое число записывается в шестнадцатеричном виде (начинаются с 0x) нужно обрамлять кавычками. Если вначале идёт ноль, то это целое значение в восьмеричном виде.

Число с единицей измерения - некоторые числовые параметры имеют неявную единицу измерения, так как они описывают объем памяти или времени. Если указать число без единицы измерения, то число может трактоваться как байт, килобайт, блок, миллисекунды, секунды, минуты. Единицу измерения можно узнать из столбца unit представления pg_settings. Удобно использовать в качестве суффикса единицу измерения. Её можно указывать сразу после числа или через один пробел. В любом случае, обязательно обрамлять значения апострофами. Допустимые единицы измерения памяти (регистр важен):

B (байты), kB (килобайты), MB (мегабайты), GB (гигабайты) и TB (терабайты).

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

us (микросекунды), ms (миллисекунды), s (секунды), min (минуты), h (часы) и d (дни).

Enum - записываются так же, как и строковые параметры, но ограничены набором допустимых значений, нечувствительных к регистру. Список значений указан в столбце enumvals представления pg_settings.


Параметры специфичные для СУБД Tantor

Параметры специфичные для СУБД Tantor

СУБД «Tantor» имеет улучшения. Часть улучшений является расширениями, часть встроено в ядро. Многие улучшения настраиваются параметрами конфигурации.

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

autonomous_session_lifetime

commit_ts_buffers

libpq_compression

multixact_members_buffers

multixact_offsets_buffers

notify_buffers

serial_buffers

subtrans_buffers

transaction_timeout

wal_sender_stop_when_crc_failed

xact_buffers

Отличия СУБД «Tantor» от PostgreSQL описаны в разделе документации:

https://docs.tantorlabs.ru/tdb/ru/15_6/se/differences.html 

autonomous_session_lifetime

Параметр autonomous_session_lifetime задает максимальное время жизни автономной сессии. Значение по умолчанию 300 минут (5 часов). Что это такое?

Автономные транзакции можно реализовать например через dblink к своей же базе, но проблема в производительности. СУБД Tantor обеспечивает высокоскоростную реализацию автономных транзакций благодаря своей архитектуре. Создается пул автономных сессий, обслуживающимися фоновыми рабочими процессами (background workers). Пул порождается при создании первой автономной транзакции. Серверные процессы выхватывают из пула сессию, передают на выполнение операторы автономной транзакции и возвращают соединение в пул. Таким образом не тратятся ресурсы на порождение-остановку процессов, обслуживающих автономные транзакции. Серверный и фоновый процессы обмениваются данными синхронно через разделяемую память. Параметр autonomous_session_lifetime заставляет пересоздавать автономные сессии, чтобы избежать возможные ошибки с неограниченным по времени использованием разделяемой памяти. Допускаются вложенные автономные транзакции. Для обслуживания вложенных автономных транзакций запускаются дополнительные (до сотни) фоновые процессы.

Пример как работает автономная транзакция:

CREATE TABLE tbl (a int);

CREATE OR REPLACE FUNCTION func() RETURNS void

LANGUAGE plpgsql

AS $$

DECLARE

 PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN

 INSERT INTO tbl VALUES (1);

END;

$$;

START TRANSACTION;

SELECT func();

ROLLBACK;

SELECT * FROM tbl;

Реализация автономных транзакций предложена Tantor Labs сообществу постгрес:

https://www.postgresql.org/message-id/[email protected] 

commit_ts_buffers

Указывает количество памяти, используемой для кэширования содержимого директории PGDATA/pg_commit_ts хранящей данные времени фиксации транзакций. Если это значение указано без единиц измерения, оно принимается в блоках (8Кб). Значение по умолчанию - 0, что равно размеру размер разделяемого пула буферов деленному на 1К (shared_buffers/1024), но не менее 4 блоков. Этот параметр может быть установлен только при запуске экземпляра.

Буфер используется, если track_commit_timestamp=on (по умолчанию off)

Обсуждение параметра:

https://www.postgresql.org/message-id/CA+hUKGKEdeVKpOqBxzRF+Z4=j0T+CA7ERrXni5De71Mm6-dBWA@mail.gmail.com 

libpq_compression

Параметр libpq_compression включает поддержку сжатия в библиотеке libpq, реализованная новым параметром в конфигурации libpq_compression. Функционал может использоваться клиентскими приложениями и драйверами, написанными на C или других языках, поддерживающих вызовы API к C.

Параметр libpq_compression может принимать следующие значения: off, on, lz4, zlib. По умолчанию libpq_compression = off.

Сжатие особенно полезно для импорта/экспорта данных с использованием команды COPY и для операций репликации (как физической, так и логической). Сжатие также может сократить время отклика для запросов, возвращающих большое количество данных (например, JSON, BLOB, текст и т.п.)

Этот параметр управляет доступными методами сжатия трафика между клиентом и сервером. Он позволяет отклонять запросы на сжатие, даже если сервер поддерживает эту функцию (например, из-за соображений безопасности или потребления процессорного времени). Для более точного контроля можно указать список разрешенных методов сжатия. Например, чтобы разрешить только методы lz4 и zlib, можно установить значение параметра в lz4, zlib. Также можно указать максимальный уровень сжатия для каждого метода, например, установив значение параметра в lz4:1,zlib:2, максимальный уровень сжатия для метода lz4 будет установлен 1, а для метода zlib 2. Если клиент запрашивает сжатие с более высоким уровнем сжатия, то будет установлен максимально допустимый уровень. По умолчанию максимально возможный уровень сжатия для каждого алгоритма 1.

Появился начиная с версии 15.4

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-connection.html#GUC-LIBPQ-COMPRESSION 

multixact_members_buffers и multixact_offsets_buffers

multixact_offsets_buffers и multixact_members_buffers задают количество разделяемой памяти, используемой для кэширования содержимого двух поддиректорий PGDATA/pg_multixact. Если значение указано без единиц измерения, оно принимается в блоках (8Кб). Значение по умолчанию 8. Этот параметр может быть установлен только при запуске сервера.

Вакуумирование позволяет удалять старые файлы из подкаталогов pg_multixact/members и pg_multixact/offsets.

Мультитранзакции используются для поддержки блокировки строк несколькими транзакциями. Поскольку в заголовке кортежа есть только ограниченное место для хранения информации о блокировке, эта информация кодируется в виде «идентификатора нескольких транзакций», или сокращенно multixact ID, когда более одной транзакции одновременно блокируют строку. Информация о том, какие идентификаторы транзакций включены в конкретный идентификатор мультитранзакции, хранится отдельно в подкаталоге pg_multixact.

В Tantor SE используются 64-битные идентификаторы транзакций, которые вряд ли до максимума своего значения и не требуют арифметики по модулю 32 для их сравнения. На уровне страницы проблема wrap around возможна, если какая-то сессия удерживает моментальный снимок, в котором накопилось более 4 миллиардов транзакций.

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

\dconfig autovacuum_*age

         List of configuration parameters

              Parameter              |    Value    

-------------------------------------+-------------

 autovacuum_freeze_max_age           | 10000000000

 autovacuum_multixact_freeze_max_age | 20000000000

Показаны значения 10 миллиардов и 20 миллиардов, что больше чем 4 миллиарда, являющегося максимумом для 32-битных чисел.

Некоторые экземпляры сталкиваются с деградацией производительности и администраторы их эксплуатирующие вынуждены либо перекомпилировать PostgreSQL увеличивая в исходном коде размеры буферов и желают, чтобы размеры буферов («SLRU кэши») конфигурировались параметрами (архитектура GUC - grand unified configuration).

https://www.postgresql.org/message-id/[email protected] 

serial_buffers

serial_buffers задаёт количество общей памяти, используемой для кэширования содержимого PGDATA/pg_serial. Если значение указано без единиц измерения, оно принимается в блоках (8Кб). Значение по умолчанию 16. Этот параметр может быть установлен только при запуске сервера.

pg_serial хранит информацию о завершённых транзакциях уровня SERIALIZABLE. Это один из SLRU буферов.

subtrans_buffers

subtrans_buffers задаёт количество общей памяти, используемой для кэширования содержимого PGDATA/pg_subtrans. Если значение указано без единиц измерения, оно принимается в блоках (8Кб). Значение по умолчанию 8. Этот параметр может быть установлен только при запуске сервера.

Подтранзакции могут явным образом запускаться как при помощи команды SAVEPOINT, так и другими способами, например посредством предложения EXCEPTION языка PL/pgSQL. То есть подтранзакции используются достаточно активно.

Идентификатор непосредственной родительской транзакции каждой подтранзакции записывается в каталог pg_subtrans. Идентификаторы транзакций верхнего уровня не записываются, поскольку у них нет родительской транзакции. Также не записываются и идентификаторы подтранзакций в режиме только для чтения.

Чем больше подтранзакций остаётся открытыми в каждой транзакции (в отношении которых не выполнен откат или освобождение), тем выше будут издержки. В общей памяти для каждого серверного процесса (backend) кэшируется по умолчанию до 64 открытых subxid. После превышения этого значения издержки на дисковый ввод-вывод существенно возрастают, так как приходится искать данные о subxid в pg_subtrans. Параметр subtrans_buffers позволяет этого избежать.

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

transaction_timeout

transaction_timeout позволяет отменить любую транзакцию или одиночную команду, длительность которой превышает указанный период времени, а не только простаивающую. Действие параметра распространяется как на явные транзакции (начатые с помощью команды BEGIN), так и на неявно начатые транзакции, соответствующие отдельному оператору. Появился в версии СУБД Tantor 15.4 Если это значение указано без единиц измерения, оно считается в миллисекундах. Значение ноль (по умолчанию) отключает таймаут.

Длительные транзакции, одиночные SELECT (потому что используют снимок данных), удерживают горизонт событий базы данных. Это не даёт вычищать старые версии строк.

Для защиты от долгих SELECTов может использоваться параметр old_snapshot_threshold. Его не стоит устанавливать на физических репликах. В 17 версии old_snapshot_threshold планируется убрать и transaction_timeout позволяет его заменить.

Однако, у old_sanpshot_threshold есть документированная особенность: если он установлен в значение больше нуля, то вакуум и автовакуум не усекает на последней фазе своей работы файлы, а значит не устанавливает блокировку ACCESS EXCLUSIVE хоть и на короткое время, но ожидание получения. этой блокировки может затянуться. Усечение файла будет происходить не на всех таблицах, а только если после вакуумирования ожидается освобождение более чем 1000 страниц (8 мегабайт).

Для защиты от простаивающих транзакций можно использовать idle_in_transaction_session_timeout.

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-resource.html 

wal_sender_stop_when_crc_failed

СУБД Tantor защищается от повреждения данных на устройствах хранения, которые могут возникнуть из-за повреждения блоков от момента передачи блока операционной системе до момента последующего чтения этого блока. Это обеспечивается подсчетом контрольных сумм по простому, быстрому, но достаточному для обнаружения повреждений алгоритму CRC-32.

В СУБД Tantor по умолчанию при создании кластера в момент инсталляции включается расчет и проверка контрольных сумм блоков данных (вызывается утилита initdb с ключом -k). Если создавать кластер после инсталляции утилитой initdb, то по умолчанию (также как в PostgreSQL) кластер создается без подсчета контрольных сумм на блоках данных.

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

Если wal_sender_stop_when_crc_failed установлено в значение true, то фоновый процесс walsender, который используется для передачи журнальных записей репликам и другим клиентам (утилите pg_recevewal), читает WAL-сегменты из файловой системы. Если он обнаруживает неверную контрольную сумму, то пытается прочесть запись из буфера памяти (WAL buffer). Если попытка не увенчается успехом, walsender остановится. Это позволит избежать распространения сбойных страниц на реплики и архивы WAL. По умолчанию значение false.

xact_buffers

xact_buffers задаёт количество общей памяти, используемой для кэширования содержимого PGDATA/pg_xact подкаталога о статусе фиксации транзакций. Если это значение указано без единиц измерения, оно принимается в блоках (8Кб). Значение по умолчанию - 0, что равно размеру размер разделяемого пула буферов деленному на 512 (shared_buffers/512), но не менее 4 блоков. Этот параметр может быть установлен только при запуске экземпляра.

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

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

Статус фиксации использует два бита на транзакцию (зафиксирована COMMIT или отменена ROLLBACK), поэтому если autovacuum_freeze_max_age установлено на максимально допустимое значение в два миллиарда, размер pg_xact ожидается около полугигабайта, а pg_commit_ts - около 20 ГБ. Если это незначительно по сравнению с общим размером вашей базы данных, рекомендуется установить autovacuum_freeze_max_age на максимально допустимое значение, так как единственным недостатком увеличения значения autovacuum_freeze_max_age (а также vacuum_freeze_table_age вместе с ним) является то, что подкаталоги pg_xact и pg_commit_ts кластера базы данных будут занимать больше места.

Или установите autovacuum_freeze_max_age в зависимости от того, сколько места вы готовы выделить для хранения pg_xact и pg_commit_ts. (Значение по умолчанию, 200 миллионов транзакций, соответствует примерно 50 МБ для хранения pg_xact и около 2 ГБ для хранения pg_commit_ts).

Сохраняются статусы и подтранзакций. При фиксации или откате транзакции верхнего уровня статусы подтранзакций (два бита на каждую) также записываются в подкаталог pg_xact. При прерывании транзакции верхнего уровня все её подтранзакции также прерываются.


Предустановленные параметры

Параметры контекста internal

В 16 версии есть 18 параметров, значения которых нельзя поменять. Они не устанавливаются в файлах конфигурации и доступны только для чтения.

Часть параметров задана при сборке и устанавливает ограничения (лимиты) постгрес. Часть параметров описательная - отражение текущего режима работы экземпляра или кластера и при смене режима по документированной процедуре изменит значение.

Список параметров этого типа (internal) можно посмотреть запросом:

select * from pg_settings where context='internal' order by 1;

Параметры, значения которых могут меняться:

in_hot_standby - описательный параметр для реплики

data_directory_mode - описательный, показывает разрешения, которые были установлены на data_directory (PGDATA) на момент запуска экземпляра

server_encoding - задаётся при создании кластера

server_version и server_version_num - процедурой обновления версии

wal_segment_size - меняется утилитой pg_resetwal

shared_memory_size* - описательные параметры, зависят от huge_page_size

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-preset.html 

Задание параметров при создании кластера

Утилита создания кластера initdb имеет параметры (ключи), которые задают свойства создаваемого кластера. На initdb влияют и переменные окружения, установленные перед запуском утилиты. Параметры initdb перекрывают значения, заданные переменными окружения. Часть параметров нельзя изменить после создания кластера.

Часть параметров, заданных при создании кластера может меняться после его создания.

Параметр утилиты initdb &ndash;k или --data-checksums задает подсчет контрольных сумм в блоках файлов данных, находящихся в табличных пространствах. В СУБД Tantor подсчет контрольных сумм включён по умолчанию, если кластер создается утилитой установки. Если утилита initdb запускается вручную, то она работает как в PostgreSQL и подсчет кластер создаётся без установки подсчета контрольных сумм.

Включить, выключить или проверить контрольные суммы файлов можно утилитой pg_checksums. Для проверки бэкапов используется pg_verifybackup. Узнать включены ли контрольные суммы на кластере можно утилитой pg_controldata или посмотреть значение параметра конфигурации (только для чтения) data_checksum.

pg_controldata -D . | grep checksum

Data page checksum version:           0 

Ноль означает отключено. Отличное нуля значение - включено.

Не рекомендуется отключать проверку контрольных сумм. Если возникнет повреждение блока данных на диске при доступе к этому блоку процессы, в том числе процессы очистки не смогут продолжить работу. Это может привести к невозможности очистки и заморозки страниц.

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/locale.html 

Разрешения на директорию PGDATA

Разрешения на директорию PGDATA устанавливаются при создании кластера. Параметр initdb -g или --allow-group-access устанавливает разрешения 0750 (rwx r-x ---) на директорию и ее содержимое, позволяющее членам группы читать содержимое PGDATA, что может быть удобно для резервирования. После создания кластера можно вручную поменять разрешения на уровне файловой системы (chmod -R 750 $PGDATA) установив для PGDATA и ее поддиректорий маску 0750 или 0700 (rwx --- ---).

При запуске кластера проверяется, что на PGDATA установлены разрешения либо 0750, либо 0700. Если разрешения другие, то кластер не запустится:

pg_ctl start -D .

waiting for server to start....

FATAL:  data directory "/var/lib/postgresql/tantor-se-16/data" has invalid permissions

DETAIL:  Permissions should be u=rwx (0700) or u=rwx,g=rx (0750).

stopped waiting

Параметр data_directory_mode контекста internal показывает значение с которыми был запущен кластер:

select name, setting, min_val, max_val from pg_settings where context ='internal' and name like 'data_di%';

        name         | setting | min_val | max_val

---------------------+---------+---------+---------

 data_directory_mode | 0750    | 0       | 511

(1 row)

Историческая справка: в PostgreSQL 10 версии было одно допустимое значение 0700. До 10 версии ограничений не было. В 11 версии добавили 0750.

Размер блока данных

По умолчанию размер страницы (блока данных) составляет 8 килобайт (или 8192 байт). Размер блока данных задан при компиляции и в 16 версии не может быть изменён без перекомпиляции программного обеспечения. Он определяется макросом BLCKSZ который по умолчанию установлен в 8Кб (8192 байт) в файле /opt/tantor/db/16/include/pg_config.h 
Узнать размер блока можно

pg_controldata | grep 'block size'

Database block size:                  8192

WAL block size:                       8192

или параметром конфигурации block_size

Размер блока данных определяет лимиты постгрес.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/limits.html 


Ограничения

Размер блока данных может быть 16Кб, 32Кб. В настоящее время эмпирически (опытным путём) выбран 8Кб. Он определяется текущим развитием hardware (например, размерами кэшей). Внутренние алгоритмы работы, константы, параметры выбирались исходя из размера блока 8Кб. При изменении размера блока возможно появление узких мест под большой нагрузкой.

Отношениями (синоним «класс») называются таблицы, индексы, последовательности, представления, внешние (foreign) таблицы, материализованные представления, составные типы.

Если объем хранимых данных в таблице будет превышать 32Тб, стоит использовать секционированные (partitioned) таблицы.

Размер блока влияет на максимальный размер отношения. Большие значения полей до 1Гб можно хранить в столбцах типа text, varchar, bytea. Это ограничение следует из того, что максимальный размер поля в TOAST таблице 1Гб.

Можно использовать устаревший тип данных lo. Все значения этого типа в одной базе данных хранятся в одной таблице системного каталога. Так как максимальный размер несекционированной таблицы 32Тб, то и максимальный объем lo в одной базе тоже 32Тб. Например, в одной базе можно хранить не больше 8 полей размером по 4Тб.

Количество столбцов, по которым можно создать индекс ограничено макросом INDEX_MAX_KEYS. Значение константы показывает параметр max_index_keys.

Также есть ограничение на количество параметров функций равное 100, но оно может быть увеличено до 600 (при размере блока 8Кб) перекомпиляцией.

cat pg_config_manual.h | grep FUNC_MAX_ARGS

#define FUNC_MAX_ARGS                100

Максимальный размер строкового буфера (MaxAllocSize в stringinfo.c)  0x3fffffff = 1 Гигабайт минус 1 байт. В СУБД Тантор начиная с версии 16.2 - 2 Гигабайта при использовании параметра enable_large_allocations. При обработке строк (команды SELECT * и COPY) выделяется память под строковый буфер. Если размер обрабатываемых данных больше и буфер при очередном увеличении своего размера выходит за этот лимит, то выдаётся ошибка: "Cannot enlarge string buffer".

Ограничения на длину идентификаторов

Максимальная длина идентификаторов (например, имен таблиц, столбцов, индексов и т. д.) составляет 63 символа. Это означает, что идентификатор может содержать до 63 символов. Это стандартное ограничение и оно применяется ко всем идентификаторам в базе данных.

Например, вы можете создать таблицу с именем, содержащим до 63 символов:

CREATE TABLE my_really_long_table_name_with_63_characters (...);

Или столбец с именем, также содержащим до 63 символов:

ALTER TABLE my_table_name ADD COLUMN my_really_long_column_name_with_63_characters INTEGER;

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

==================

Идентификаторы превышающие этот размер усекаются, о чем выдается предупреждение

create table шестьдесяттрисимвола456789 (n numeric);

NOTICE:  identifier "шестьдесяттрисимвола456789" will be truncated to "шестьдесяттрисимвола"

CREATE TABLE

\d ш*

Table "public.шестьдесяттрисимвола"

 Column |  Type   | Collation | Nullable | Default

--------+---------+-----------+----------+---------

 n      | numeric |           |          |

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

Максимальная длина идентификатора определяется константой NAMEDATALEN-1 установленной при компиляции. Значение константы показывает параметр max_identifier_length

postgres=# show max_identifier_length;

 max_identifier_length

-----------------------

 63

(1 row)

Есть и другие ограничения, например, максимальное количество аргументов функции 100, параметров в запросе 65535.


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

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

«Конфигурационные параметры» (config) и «параметры конфигурации» (settings) созвучны, но это разные понятия.

Часть параметров задаётся при сборке (компиляции, линковке). Посмотреть большую часть параметров, заданных при сборке:

  1. Утилитой командной строки pg_config
  2. Функцией select * from pg_config();

Например, SHAREDIR определяет директорию с файлами расширений.

Вопрос, который может возникнуть: установил расширение, хочу посмотреть что в него входит. Самое простое найти текстовые файлы расширений и посмотреть в них команды и параметры. Где найти эти файлы? Ответ: управляющие файлы расширений лежат в в поддиректории extension директории SHAREDIR,  путь к которой можно посмотреть командой: /usr/share/postgresql/12/extension.

Список управляющих файлов расширений:

ls $(pg_config --sharedir)/extension/*.control

Второй вопрос: загрузил разделяемую библиотеку, где лежит ее файл? Или - хочу загрузить библиотеку, куда скопировать её файл? Ответ: PKGLIBDIR указывает на директорию разделяемых библиотек по умолчанию (файлы с расширением .so). Библиотеки могут загружаться командой LOAD в сессии или параметром shared_preload_libraries.

pg_config --pkglibdir

/opt/tantor/db/16/lib/postgresql

BINDIR определяет директорию с исполняемыми файлами, путь которой добавляется в переменную окружения PATH пользователя postgres (файл .bash_profile) в процессе инсталляции Tantor DB.

cat .bash_profile

export PATH=$PATH

export PATH=/opt/tantor/db/16/bin:$PATH

PGSYSCONFDIR указывает директорию, где находится файл служб подключений pg_service.conf

Если в файле служб создать описание службы, то можно будет им пользоваться psql "service=описание_службы"

В Oracle Database файл служб имеет аналог в виде файла tnsnames.ora. Файл pg_service.conf не востребован, он не используется JDBC-драйверами, только libpq.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/libpq-pgservice.html 


Раздел 4. Базы данных

Логическая структура кластера

Кластер базы данных

Кластер баз данных

Определения понятия «кластер баз данных» в документации дано следующим образом.

Кластер (объединение) баз данных или сокращённо «кластер» - это базы данных, имеющие общие глобальные SQL-объекты и их общих статических и динамических метаданных. Кластер баз данных создаётся утилитой командной строки initdb. SQL-объект - любой объект, который может быть создан командой CREATE языка SQL. Глобальные SQL-объекты - это роли, табличные пространства, источники репликации, подписки логической репликации, базы данных. Локальные SQL-объекты это те, которые не глобальные. Базы данных - именованный набор локальных SQL-объектов.

Определение аккуратное, но кажется непонятным, хотя бы потому, что «общие статические», а особенно «динамические метаданные» в списке определений не даны.

Если вы работали с Oracle Database, то аналог базы данных PostgreSQL («постгрес») это Pluggable Database (PDB). Аналог кластера - multitenant container database. Корневой базы (CDB Root) в постгрес нет, для управления кластером постгрес можно подключиться к любой из баз данных. Аналог Oracle Seed PDB - это база данных template0 или template1.

Рассмотрим понятие «базы данных» с другой стороны. Приложению нужно хранить данные, оно их хранит в виде таблиц и других объектов. Для хранения приложение создаёт соединения с местом хранения, которое можно назвать базой данных. Место, где могут совместно располагаться (храниться, находиться) объекты, с которыми можно работать одновременно (например, соединять таблицы в одной выборке), является для приложения логическим местом для хранения - «базой данных».

Чтобы создать место хранения, нужно запустить утилиту initdb. Эта утилита создаст набор файлов и директорий в физическом месте хранения - директории путь к которой указывается в параметрах initdb. Эту директорию называют PGDATA. В PGDATA хранится кластер баз данных. Чтобы приложения могли подсоединиться к какой-нибудь базе данных (понятия подсоединиться к кластеру нет, одно соединение оно же сессия подсоединяется к одной базе данных) нужно чтобы на хосте (он же сервер или компьютер) был запущен «экземпляр» - набор серверных, фоновых (вспомогательных) процессов и основной процесс postgres (он же postmaster). Изначально создаётся три базы данных, позже, запустив кластер, можно командой CREATE DATABASE создать базу данных в кластере. Подсоединяться при этом можно к любой базе данных кластера, база данных будет создана и будет равной среди всех остальных баз данных кластера.

В Oracle Database есть созвучная технология Real Application Cluster (RAC) - набор одного или нескольких экземпляров, обслуживающих CDB или non-CDB. RAC не является аналогом понятия «кластер баз данных» постгрес. В постгрес один кластер обслуживает один экземпляр (instance).

https://docs.tantorlabs.ru/tdb/ru/15_6/se/glossary.htm 

Экземпляр

Экземпляр (instance) кластера баз данных постргес - набор процессов и используемой ими памяти (общей для них и локальной для каждого из этих процессов) посредством которых приложения подсоединяются (создают сессии) к базам данных. Базам данных кластера, так как один экземпляр обслуживает ровно один кластер. В кластере же можно создавать и удалять базы данных. Экземпляр постгрес то же самое, что экземпляр single-instance Oracle Database.

Детализируем: экземпляр - это один процесс postgres (postmaster) набор серверных (обслуживающих, backend, foreground), вспомогательных (фоновых) процессов, которые используют разделяемую память чтобы обмениваться данными между собой и достигать синергии совместно используя структуры памяти которые располагаются в общей области памяти. На одном сервере могут работать несколько экземпляров СУБД, если не будет конфликта по номеру порта, в том числе в имени файла Unix-сокета.

Что за «порт»? Это число, которые устанавливается в параметре конфигурации port. По умолчанию 5432. Порт используется в имени Unix-сокета (файл) и как номер TCP портов сетевых интерфейсов (IP-адресов), которые перечислены в параметре local_addresses. Значение по умолчанию localhost.  * - все адреса IPV4 и IPV6, '0.0.0.0' - все адреса IPv4, '::' - все адреса IPv6.  Но можно задать список имён и/или числовых IP-адресов узлов, разделённых запятыми. Пустая строка означает, что подключиться к экземпляру можно будет только через Unix-сокет.

Процесс экземпляра postgres прослушивает этот порт. В Oracle Database этим занимаются процессы прослушиватели (listeners), не принадлежащие экземплярам.

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

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

Примечание: Название postmaster используется для обозначения основного процесса экземпляра, так как слово постгрес может обозначать много понятий, например семейство СУБД, к которому относится СУБД Tantor. СУБД Tantor - ответвление (fork) свободно распространяемого PostgreSQL, как и остальные forks: Enterprise DB, Postgres Pro Enterprise.


Базы данных

База данных

Приложение хранит данные в СУБД и получает к ним доступ через соединение (connection) с серверным процессом экземпляра. В рамках соединения (локального через Unix-сокет или сетевой TCP-сокет) создается сеанс. Сеанс, соединение, сессия, подключение часто (в документации somtimes) используются как синонимы, потому что для приложения важно давать команды SQL и получать результат. Отличия соединений от сессий играют роль при настройке балансировщиков нагрузки (например, приложение pgBouncer) и сетевых настроек. Соединение - физическое понятие, сессия - логическое.

Создав соединение, приложение должно иметь доступ ко всем своим объектам. Например, иметь возможность соединять выборки из нескольких таблиц и использовать свои хранимые функции. Поэтому все (за небольшим исключением) объекты хранения, которые использует приложение локальны для базы данных, хранятся в ней.

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

Идеи изоляции приложений с помощью баз данных и объединения объектов приложения в одной базе данных технически можно обойти, так как потребности у приложений разные. Например, используя расширения (видов fdw, dblink) приложение в своей сессии может работать с данными в нескольких базах данных. А несколько приложений используя схемы и роли могут хранить таблицы с одинаковыми именами в одной базе данных не мешая друг другу.

Список баз данных

Изначально после создания кластера есть три базы данных с именами postgres, template0, template1. К базе template0 нельзя подсоединиться, она не предназначена для внесения в неё изменений. Список баз можно получить:

командами psql \l или \l+

командой SELECT datname FROM pg_database;

или графическими утилитами, например pgAdmin.

Создание баз данных

Базу данных может создать роль с атрибутом SUPERUSER или CREATEDB:

CREATE DATABASE имя_базы параметр = значение параметр = значение;

У команды есть утилита-обёртка createdb, она удобна если хочется создавать базы данных из командной строки.

В команде имеется около 15 параметров. Можно обратить внимание на следующие параметры:

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

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

TEMPLATE - имя базы содержимое которой вы скопируете. Это любая база, не обязательно имеющая свойство IS_TEMPLATE. По умолчанию используется template1. Но если вы захотите создать базу с параметрами локализации отличными от тех, что указаны у template1 нужно использовать template0 (unmodifiable empty database).

IS_TEMPATE можно менять после создания базы. Если IS_TEMPATE= true, эту базу сможет клонировать любой пользователь с атрибутом CREATEDB; в противном случае (по умолчанию), клонировать эту базу смогут только суперпользователи и её владелец. Также база со свойством шаблона не может быть удалена. Для удаления сначала нужно убрать свойство шаблона.

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

create database имя_базы LC_COLLATE = 'ru_RU.iso88595' LC_CTYPE='ru_RU.iso88595' ENCODING='ISO_8859_5' TEMPLATE= template0;

Доступные к использованию типы сортировок можно посмотреть в таблице pg_collation. Типы сортировок "C" и "POSIX" совместимы со всеми кодировками. Не нужно их использовать, так как порядок сортировки кириллических символов не соответствует лингвистическим правилам.

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-createdatabase.html 

Изменение свойств базы данных

STRATEGY - обратите внимание на этот параметр если вы создаете базу на промышленном кластере или база, которую вы используете в качестве шаблона (которую клонируете) имеет большой размер. Параметр появился в 14 версии постгрес и сразу по умолчанию стал использовать новую стратегию WAL_LOG при которой составляется список объектов и весь объем клонируемой базы проходит через журналы предзаписи. Причина появления новой стратегии в том, что прежняя FILE_COPY выполняла контрольную точку, потом копировала директории (журналируя только команды копирования), потом вторую контрольную точку. Если шаблон маленького размера, то первая контрольная точка на промышленном кластере даёт повышенную нагрузку (вторая несущественно). Причина не только в одномоментной и косвенном возрастании объема записи  (грязный блок записывается по контрольной точке но меняется и реже будет записан второй, а мог бы один раз если бы не было контрольной точки) нагрузке на ввод-вывод (систему хранения, диски), а в том, что после каждой контрольной точки каждый изменяемы блок записывается в журнал полностью (8Кб) так как по умолчанию параметр full_page_writes=on (а отключать его небезопасно). Но если размер шаблонной базы больше значения параметра max_wal_size, то контрольная точка тоже будет выполнена и может быть даже неоднократно если размер базы больше значения параметра в несколько раз.

Если размер шаблона небольшой, например, меньше 16Мб (размер WAL-сегмента) или в несколько раз больше, то можно создавать базу данных. Если больше, то стоит выбрать время когда кластер наименее нагружен. Если есть реплики, то оценить пропускную способность сети и, возможно, указать стратегию FILE_COPY. Если размер шаблона больше например половины от max_wal_size, то FILE_COPY предпочтительнее.

Можно дать описание созданной базе данных. Описания к почти любым объектам можно давать командой:

comment on database db1 is 'Database for my purpose';

Описание можно посмотреть командой \l+

Описания на функционал не влияют.

Параметры конфигурации на уровне базы данных (ALTER DATABASE) и разрешения на уровне базы данных (GRANT) из шаблонной базы данных в клон не переносятся.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-alterdatabase.html 

Команда ALTER DATABASE

Изменить свойства базы данных можно командой ALTER DATABASE. 

Пример:

alter database имя is_template=true;

alter database имя SET имя=значение; меняет один из около 190 параметров сессий, которые можно установить на уровне базы данных.

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

Можно поменять табличное пространство по умолчанию, но к базе никто не должен быть подсоединён и на уровне файловой системы будут перемещаться все файлы (кроме тех которые находятся в других табличных пространствах) и файлы объектов системного каталога.

Можно поменять владельца базы данных.

Можно установить параметры конфигурации, чтобы настроить поведение процессов (и фоновых и обслуживающих сессии), работающих с объектами этой базы данных.

Параметры локализации можно выбрать при создании базы данных, после создания базы данных изменить нельзя. Основное это кодировка (encoding) и значения collation (правила сортировки), ctype (классификация символов) которые связаны со значением encoding, провайдер локализации. Часть параметров локализации относятся к сессии и их можно поменять командой ALTER DATABASE SET.

Создание базы данных и изменение табличного пространства нетранзакционны (нельзя выполнять в рамках транзакции). Знание о транзакционности команд имеет смысл, например, при установке или разработке расширений. Нетранзакционные команды не могут выполняться при установке расширения в базу данных.


Удаление базы данных

Если содержимое базы данных не нужно, то базу данных можно удалить.

При удалении локальные объекты в других базах данных не затрагиваются. Команда удаления:

DROP DATABASE  [IF EXISTS] имя;

В квадратных скобках опциональные ключевые слова.

IF EXISTS (если существует) есть во многих командах и позволяет не генерировать ошибку (уровень важности ERROR), если объекта нет, но обычно сообщает (уровень важности NOTICE), что такого объекта нет. Уровни важности влияют на то как будет обработано сообщение: выдано клиенту, передано в журнал сообщений кластера.

Следующая команда:

DROP DATABASE имя (FORCE); позволяет отсоединить сессии, которые соединены с этой базой, прервать их транзакции и удалить базу.

Базу данных со свойством IS_TEMPLATE (шаблона) можно удалить, если убрать свойство шаблона.

Не стоит удалять базу template0.


Схемы

Схемы

Следующий объект, который мы рассмотрим - схемы. Синоним схемы - пространство имён (namespace).

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

Схема - локальный объект базы данных. В разных базах данных могут существовать схемы с одинаковыми именами (идентификаторами).

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

Схемы позволяют объединять подпрограммы (процедуры и функции), логически связанные друг с другом.

Большинство объектов, с которыми работают приложения, должны принадлежать какой-либо одной схеме. Такие объекты не могут существовать без схемы. Перед удалением схемы нужно будет переназначить объекты в другую схему. Объект не может находиться в нескольких схемах одновременно. Аналогов симлинков и хардлинков, как в файловой системе, нет.

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

SELECT схема.функция(); или SELECT * FROM схема.таблица;

В Oracle Database есть объекты пакет и тело пакета. В PostgreSQL таких объектов нет.  Схемы могут использоваться для обеспечения основного функционала пакетов - возможности объединять схожие по логике подпрограммы в модули (пакеты). Использование расширений, реализующих пакеты путем добавления команд create package приводит к созданию непереносимого (на другие СУБД семейства PostgreSQL) кода.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/ddl-schemas.html 

Создание и изменение схем

Схемы не связаны с ролями. Имена владельца объекта и имя схемы (в которой находится объект) могут быть разными и их можно менять после создания объекта.

Схемы имеют владельца. При создании схемы его можно установить:

CREATE SCHEMA имя_схемы AUTHORIZATION владелец;

а позже поменять:

ALTER SCHEMA имя_схемы OWNER TO роль;

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

В Oracle Database схемы и пользователи связаны друг с другом, что ограничивает гибкость. В Oracle Database по этой причине есть объекты «синонимы», в постгрес аналогов  «синонимов» нет, так как они не нужны.

На схемы можно выдавать привилегии CREATE и/или USAGE ролям. Тем самым управлять «видимостью» объектов в схеме как единым целым. Аналогия: в файловой системе может быть привилегия доступа к файлу, но если нет привилегии на директорию, в которой расположен файл, то доступа к файлу не будет.

Схемы можно удалять:

DROP SCHEMA [ IF EXISTS ] имя [CASCADE] ;

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

Путь поиска

С объектами схемы связано понятие путь поиска и соответствующий параметр конфигурации search_path. Этот параметр установлен на уровне кластера и имеет значение по умолчанию "$user", public

$user - подставляется имя роли в которой текущий момент работает сессия

Этот параметр может быть установлен на любых уровнях и меняться любой ролью.

В файловых системах есть аналог - переменная окружения PATH.

В пути поиска можно указать несколько схем, в которых будет искаться объект, если перед именем объекта явно не указано имя схемы. Объект ищется по порядку перечисленных в пути поиска схем. Если схема не существует или на неё нет прав, то ищется в следующих по порядку схемах и ошибок не выдаётся. Алгоритм поиска аналогичен поиску файлов в файловой системе.

В шаблонных базах есть схема с именем public, поэтому при создании любых баз данных схема с именем public будет существовать. Схема public указана в пути поиска: "$user", public

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

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

Специальные схемы

В постгрес существуют служебные схемы:

pg_catalog - в этой схеме расположены объекты «системного каталога» - служебные таблицы, представления, функции и другие объекты.

information_schema - схема, описанная в стандарте SQL. Содержит таблицы со стандартизованными именами и названиями столбцов. Разработчики стандарта полагали что производители СУБД создадут эту схему и таблицы, что позволит разработчикам одной и той же командой SELECT получать данные работая с СУБД разных производителей.

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

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

pg_toast - схема для особых таблиц TOAST, которые используются для хранения полей большого размера. Эти таблицы стараются скрывать, чтобы они не создавали «информационный шум». В этих целях TOAST-таблицы (и их индексов) создаются в этой служебной схеме. Об этой схеме можно знать на случай если её имя где-то встретится. Работа с TOAST полностью автоматизирована и отдельных команд для работы с TOAST-объектами и схемой нет. Для изменения свойств, касающихся TOAST используются опции команд CREATE TABLE и ALTER TABLE для обычных таблиц.

pg_toast_temp (ссылка на pg_toast_tempN где N - число) - схема для временных TOAST таблиц (и индексов) к временным таблицам. Существуют не дольше жизни сессии.

pg_temp (ссылка на pg_tempN где N - число) - схема для временных таблиц. Временные таблицы, индексы, представления (их определения и данные) существуют либо до конца транзакции, либо до конца сессии.

Практический смысл имеет знание о схеме pg_catalog. Имя этой схемы можно использовать в командах psql для поиска служебных таблиц, представлений и функций.

Знания о временных объектах нужны для разработчиков и администраторов, если они сталкиваются с наличием большого количества файлов временных объектов. Использование сборки Tantor SE1C позволяет уменьшить проблемы при работе большим количеством временных объектов.

Определение текущего пути поиска

Текущий путь поиска можно получить:

командой psql SHOW search_path; выдает установленный для этого места путь поиска в виде строки. Разделители - запятые.

функцией current_schemas(false) - выдает действующий в этом месте путь поиска в виде массива. При этом, в отличие от search_path не выдаёт несуществующие схемы, только конкретные имена существующих схем. Функцию удобно использовать в хранимых подпрограммах.

current_schemas(true) - добавляет служебные схемы, а именно pg_catalog и pg_temp_N (если она была автоматически создана в сессии) если он неявно присутствует в пути поиска. Схемы для TOAST не выдаёт, так сделано. Этот вариант функции используется для определения того, будет ли искаться имя объекта сначала в схеме системного каталога. Например, ищется функция или таблица имя которой начинается с "pg_" (так начинаются названия всех объектов системного каталога), пользовательские объекты по соглашению (code conventions) которого обычно придерживаются разработчики приложений не должны иметь имена начинающиеся на "pg_". Можно поменять путь поиска так, чтобы pg_catalog шел в списке не первым, но это не имеет смысла и не практикуется.

Функцией current_schema или current_schema(). В PostgreSQL после имени функции без аргументов обязательно ставить круглые скобки "()". Однако для части функций, описанных в стандарте SQL к которым относится эта функция их ставить не обязательно, потому что в стандарте SQL круглые скобки опциональны. Эта функция выдает одно имя первой по порядку схемы в пути поиска (search_path) или NULL, если путь поиска пустой. В этой схеме будут создаваться пользовательские объекты, если в команде создания не указать явно имя схемы. Если функция выдает NULL, то объект не будет создан без указания схемы.

В какой схеме будет создан объект

Для определения схемы, в которой будет создан объект используется путь поиска, действующий в данном месте исполнения команды. Имя этой схемы для обычных объектов выдает функция current_schema(). Однако, если объект «необычный» (временный), то используются схемы, в которых могут располагаться объекты этого специфического типа. Это относится к временным таблицам, индексам на временные таблицы, временным представлениям, TOAST таблицам к временным таблицам. В этом случае если схема отсутствует, то она будет создана (или назначена из созданных ранее и неиспользуемая другими сессиями) - ей будет назначен номер и он будет использоваться как суффикс в имени схемы. В этом случае имя такой служебной схемы будет неявно существовать в пути поиска. Соответственно такие объекты неявно будут искаться и префиксировать их имена именем служебной схемы не нужно.

Таким образом, создание временной таблицы приводит к добавлению строк в таблицы системного каталога. При массированном порождении временных объектов таблицы и индексы системного каталога, а также файловая система могут стать узким местом. После окончания сессии объекты временных схем удаляются, а сама схема остается для повторного использования другими сессиями, чтобы не порождать частое удаление строк в таблице системного каталога pg_namespace.

Если нужно явно задать место в пути поиска для служебных схем, то можно указывать названия pg_catalog и pg_temp в нужном порядке среди обычных схем. Этот порядок и будет использоваться. Однако, лучше не допускать перекрытия имён объектов и делать имена уникальными, чтобы не приходилось прибегать к изменению пути поиска.

Путь поиска в подпрограммах SECURITY DEFINER

В подпрограммах со свойством SECURITY DEFINER есть особенность с путем поиска. Точнее с переменной подстановки $user. В теле подпрограмм (процедур и функций) используются права владельца (DEFINER). Функция user в таких подпрограммах выдаёт имя владельца. В пути поиска с переменной подстановки будет имя владельца. Так как $user присутствует в в значении по умолчанию, обычно создатель такой подпрограммы тестирует подпрограмму с этим значением search_path.

Если вызывающий подпрограмму поменяет перед вызовом подпрограммы search_path в своей сессии или транзакции, то именно такое значения и будет действовать в теле подпрограммы. Видимость объектов может поменяться.

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

CREATE FUNCTION имя(параметры)

 RETURNS тип

 LANGUAGE язык

 SET  search_path TO 'значение'

 SECURITY {DEFINER | INVOKER}

AS

BEGIN

END;

Если ставить SET внутри блока BEGIN и END ошибки не будет, но поведение будет другим - установленное значение останется после выхода из подпрограммы, а если произошел откат транзакции (даже неявно при наличии в подпрограмме секции EXCEPTION) изменение значения параметра отменится. Это создаёт неоднозначность и порождает трудно выявляемые ошибки.

На уровне любой (INVOKER и DEFINER) подпрограммы можно установить значение для параметра конфигурации которые допускают изменение значения на уровне сессии (контекст user, superuser).

Маскировка объектов схем

В документации написано: «Для обеспечения безопасности search_path должен быть настроен таким образом, чтобы исключить любые схемы, доступные для записи ненадежными пользователями. Это предотвращает возможность создания злонамеренными пользователями объектов (например, таблиц, функций и операторов), которые могут замаскировать объекты, предназначенные для использования функцией. Особенно важной в этом отношении является временная схема, которая по умолчанию ищется первой и обычно доступна для записи всем. Безопасное расположение может быть достигнуто путем принудительного поиска временной схемы в конце. Для этого напишите pg_temp как последний элемент в search_path

Другими словами, чтобы подпрограмма c тегом DEFINER была безопасна, search_path должен:

1) быть установлен на уровне определения подпрограммы

2) исключать любые схемы, доступные для создания или изменения пользователям с меньшим уровнем привилегий, чем у владельца такой подпрограммы

3) схема pg_temp должна быть указана явно в конце пути поиска.

Также, нужно знать, что по умолчанию, после создания подпрограммы роль PUBLIC получает право выполнять подпрограмму. Это поведение можно изменить, используя привилегии по умолчанию (default privileges).

Объекты системного каталога, в том числе функции, можно замаскировать явно указав схему pg_catalog в пути поиска после схемы с маскирующим объектом. Например: SET search_path = public, pg_catalog;

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-createfunction.html 


Системный каталог

Системный каталог - понятие

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

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

Объекты системного каталога располагаются в схеме pg_catalog.

В Oracle Database аналог системного каталога называется «словарём данных» (data dictionary).

Названия объектов приводятся к нижнему регистру и хранятся в нижнем регистре (если не использовались двойные кавычки при задании имён).

Объекты системного каталога (кроме глобальных) всегда располагаются в табличном пространстве по умолчанию для базы данных.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/catalogs.html 

Общие объекты кластера

В кластере есть и глобальные объекты, информация о них хранится в нескольких таблицах (глобальные объекты кластера), которые располагаются в табличном пространстве pg_global. Эти таблицы видны одинаковым образом в сессиях, соединённых с любой базой данных кластера. В 16 версии СУБД «Tantor» к глобальным объектам относятся 11 таблиц и 21 индекс на их столбцы, 9 TOAST таблиц и 9 индексов на TOAST таблицы. Всего 50 объектов.

Общие объекты кластера:

  1.  базы данных - таблица pg_database
  2.  роли - pg_authid, pg_auth_members
  3.  табличные пространства pg_tablespace
  4.  подписки логической репликации pg_subscription
  5.  источники логической репликации - pg_replication_origin, pg_shseclabel, pg_shdepend, pg_shdescription

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

Роли, табличные пространства, источники репликации, подписки логической репликации, а также сами базы данных не являются локальными SQL-объектами, так как они существуют вне какой-либо отдельной базы; они называются глобальными объектами. Имена таких объектов должны быть уникальными во всём кластере баз данных.

Использование системного каталога

Изменения в таблицы системного каталога вносятся в процессе выполнения команд DDL. Таблицы системного каталога не заблокированы от внесения изменения. Вносить в таблицы системного каталога изменения, если это не документировано, напрямую командами SQL нежелательно. Выбирать данные из таблиц системного каталога напрямую командами SELECT и WITH возможно и используется в коде приложений и при администрировании кластера. Однако структура таблиц системного каталога не очень удобна для чтения человеком. Структура создавалась много лет назад, когда размеры систем хранения были небольшими, как и память на компьютерах. Для удобства работы с системным каталогом есть представления, которыми удобно пользоваться.

Получить список представлений системного каталога можно командой psql \dvS

Суффикс S в конце команд psql позволяет выдавать содержимое системного каталога, которые обычно по умолчанию не выдаются.

Более практична робота с с системным каталогом с помощью команд psql. Команда \? выдает список всех команд psql. Выдастся в том числе и справка по самой команде \?:

Справка

\? [commands] справка по командам psql (то есть начинающихся с символа \)

\? options    справка по параметрам командной строки утилиты psql

\? variables  справка по переменным на которыми меняется поведение psql

\h [ИМЯ]     справка по SQL-команде; * - по всем командам

Зная архитектуру постгрес, понятия, термины вы сможете легко получать информацию командами psql.

Обращение к системному каталогу

Можно обращаться к таблицам и представлениям системного каталога командой SELECT. Имена таблиц и представлений можно получить командой psql \dtvS pg_*термин*

По названию таблицы или представлению понять какая таблица или представление содержит нужную информацию. Дальше командой \d имя получить названия столбцов. Первые три символа в названии столбцов таблиц системного каталога по традиции содержат буквосочетание похожее на название таблицы где этот столбец создан. Например, в pg_namespace префикс "nsp". Начиная с четвертого символа обычно присутствует английское слово или его понятное сокращение.

Если на таблицу или столбцы созданы комментарии, то посмотреть их можно добавив "+" к команде \d+ имя_объекта. К сожалению, описания к таблицам системного каталога не заданы. Описания можно посмотреть в документации.

В таблицах системного каталога первый столбец называется oid и тип у него oid. Посмотрим описание типа командой \dT oid

                     Список типов данных

   Схема    | Имя |                 Описание                  

------------+-----+-------------------------------------------

 pg_catalog | oid | object identifier(oid), maximum 4 billion

(1 строка)

К этому типу дано описание, в котором написано, что максимальное количество значений 4 миллиарда. Отсюда следует, что в таблице системного каталога может быть не больше 4 миллиардов строк. Это означает, что если есть таблица для хранения типов (pg_class), то может быть не больше 4 миллиардов типов в одной базе данных. Также не больше 4 миллиардов отношений в одной базе данных. На столбец oid таблиц системного каталога создан индекс, а сам столбец является первичным ключом. Если количество строк в таблице системного каталога достигнет 4 миллиардов, то экземпляр и его процессы продолжат работать. В столбец oid значения вносятся автоинкрементом. По достижении 4 миллиардов серверные процессы, обслуживающие команды, которым нужно вставить новую строку в какую-либо таблицу системного каталога, будут выполнять поиск неиспользуемого значения (такие могут накопиться, значения в oid освобождаются после удаления объекта) в столбце oid, что приведет к замедлению выполнения команд. Не стоит миллиардами создавать объекты и затем миллиардами удалять их. Также надо помнить, что вакуумирование и заморозка работает и для таблиц системного каталога.


reg-типы

Чтобы получить данные из таблиц системного каталога может потребоваться соединить несколько таблиц. Строки таблиц системного каталога связаны через столбец oid, то есть число. В постгрес можно создавать типы данных (CREATE TYPE) приведения типов (CREATE CAST). Этим пользуются и разработчики постгрес. Были созданы 11 типов данных и привидения типов, которые позволяют легко преобразовывать oid (число) в столбце одной из 11 таблиц системного каталога к имени объекта в этой таблице и обратно. Эти типы называются reg-типами. Использование reg-типов и привидений типов позволяет писать запросы к таблицам системного каталога не используя соединений (JOIN) и тем самым упрощая команду выборки.  psql при обслуживании своих команд начинающихся на "\" формирует команду SELECT к таблицам системного каталога и иногда использует приведения типов. Такие SELECT можно посмотреть установив переменную \pset ECHO_HIDDEN on

Список reg-типов можно посмотреть командой \dT reg*

 Список типов данных

   Схема    |      Имя      |               Описание              

------------+---------------+--------------------------------------

 pg_catalog | regclass      | registered class

 pg_catalog | regcollation  | registered collation

 pg_catalog | regconfig     | registered text search configuration

 pg_catalog | regdictionary | registered text search dictionary

 pg_catalog | regnamespace  | registered namespace

 pg_catalog | regoper       | registered operator

 pg_catalog | regoperator   | registered operator (with args)

 pg_catalog | regproc       | registered procedure

 pg_catalog | regprocedure  | registered procedure (with args)

 pg_catalog | regrole       | registered role

 pg_catalog | regtype       | registered type

(11 строк)

Пример: SELECT relname, reltoastrelid::regclass FROM pg_class WHERE  reltoastrelid>0 AND relnamespace='pg_catalog'::text::regnamespace order by 1; - выдаст названия TOAST таблиц 36 таблиц системного каталога, у которых они есть.

Часто используемые команды psq

\l - список (list) баз данных.

\du или \dg - список ролей (user, group) кластера, \drg - назначения ролей ролям.

\dn - список схем базы (namespace).

\db - список табличных пространств.

\dconfig *имя* - список параметров конфигурации (config) кластера.

\ddp - список привилегий по умолчанию (default privileges). Это особый тип привилегий или отзывающих привилегий, специфичный для постгрес.

\dfS pg* - список системных функций (function) и процедур, полезных для администрирования. Часть информации о работе экземпляра и кластера можно получить только с помощью функций. Некоторые служебные представления используют функции. Процедуры появились в постгрес позже функций, поэтому "f" используется и для процедур.

\dvS pg* - полезные системные (System) представления (view).

\dx - список установленных расширений (extention).

\dy - список триггеров на события, которые обычно создают расширения или администраторы.

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

postgres=# \

Display all 108 possibilities? (y or n)

Список полезных администратору функций:

https://docs.tantorlabs.ru/tdb/ru/15_6/se/functions-admin.html 


Физическая структура кластера

Физическая реализация

Директория файлов кластера

Файлы кластера баз данных хранятся в директории, которую называют PGDATA по имени переменной окружения операционной системы, которую обычно устанавливают для того, чтобы не указывать утилитам управления кластера директорию при каждом вызове утилит. Параметра (ключ) у утилит называется "-D директория" или "--pgdata директория". Если утилите указать параметр, он перекроет значение переменной окружения. Некоторые утилиты (pg_resetwal) в целях избежать случайный запуск с неправильно установленной переменной окружения требуют явного указания этого параметра.

Кластер может хранить файлы данных вне директории PGDATA с помощью «табличных пространств», которые мы рассмотрим дальше в этой главе.

По умолчанию инсталлятор СУБД Tantor создает директорию /var/lib/postgresql/tantor-se-16/data
для хранения файлов кластера и файл служб
/usr/lib/systemd/system/tantor-se-server-16.service, где указывает путь к этой директории. Параметрами --edition и --major-version инсталлятору можно задать другие значения. Остальные утилиты и программное обеспечение СУБД Tantor значений по умолчанию не имеют, так как на хосте могут существовать несколько равноправных кластеров. У каждого кластера своя директория PGDATA. Каждый кластер обслуживается одним экземпляром.

По умолчанию при работе с файлами кластера используется кэш операционной системы. Параметром конфигурации для разработчиков debug_io_direct возможно установить работу с файлами данных и журнальных (WAL) файлов в режиме прямого чтения-записи (direct i/o). Практических преимуществ в производительности и отказоустойчивости для PostgreSQL этот режим не даёт. Для работы с файлами данных этот режим не стоит использовать.

PostgreSQL не дублирует (не мультиплексирует) файлы кластера. Отказоустойчивость работы с файлами должна обеспечиваться на более низких уровнях - файловой системы, оборудования.

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/storage-file-layout.html 

Директория PGDATA

В директории PGDATA находятся поддиректории с предопределёнными названиями.

По умолчанию в корне директории PGDATA располагаются текстовые файлы параметров кластера: postgresql.confpg_hba.conf и pg_ident.conf, хотя они могут размещаться в других директориях. Файл параметров postgresql.auto.conf располагается только в корне PGDATA.

current_logfiles - текстовый файл с названием текущего файла, в который сборщик сообщений записывает журнал сообщений сервера. Сборщик сообщений включается параметром конфигурации logging_collector (alter system set logging_collector = on;). Измерение параметра требует перезапуска экземпляра. Использование сборщика сообщений рекомендуется при промышленной эксплуатации или при большом объеме записываемых в журнал сообщений данных.

postmaster.opts - содержит параметры командной строки, с которыми был запущен экземпляр.

PG_VERSION - содержит номер основной версии (major release).

postmaster.pid - файл «блокировки», традиционно используемый в Линукс. Содержит номер (PID) основного процесса экземпляра; путь к PGDATA, метку времени запуска экземпляра, номер порта экземпляра, путь к каталогу Unix-сокет, IP-адрес по которому доступен экземпляр, идентификатор разделяемого сегмента памяти (SHM). Размер сегмента небольшой (56 байт). Разделяемая память по умолчанию использует тип mmap. Тип можно поменять параметром shared_memory_type, но этого делать не нужно.

Основные поддиректории:

base и global - директории двух табличных пространств, в них хранятся данные объектов кластера.

pg_stat и pg_stat_tmp директории собираемой статистики. В директорию pg_stat_tmp идёт активная запись, располагать её на SSD не стоит (большой объем записи), возможно ее стоит расположить в памяти (in-memory file system).

pg_tblspc - содержит символические ссылки на директории табличных пространства. Удобно видеть какие директории кластера располагаются вне PGDATA.

pg_wal - содержащий файлы («сегменты») журнала предзаписи (WAL - write ahead log). Потеря WAL файлов приводит к невозможности запуска кластера.

Директория log создана вручную для журнала сообщений, остальные директории.

https://postgrespro.ru/docs/postgresql/16/kernel-resources 

Временные файлы

При работе экземпляра данными, не помещающимися в память процесса создаются временные файлы. Это файлы для временных таблиц, индексов на временные таблицы, а также файлы, создаваемые при выполнении в командах SQL сортировок, соединений наборов данных, создания индексов, если не хватит памяти процесса. Память ограничивается параметрами work_mem и maintenance_work_mem.

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

Если в параметре temp_tablespaces указано несколько табличных пространств, процесс выбирает табличное пространство случайным образом при каждом создании временного объекта. Если объекты создаются в рамках транзакции, то для уменьшения задержек (на получение случайного значения) табличные пространства перебираются по кругу. Имена несуществующих табличных пространств или тех, которые не могут использоваться (нет привилегий) игнорируются и не вызывают ошибки.

Временные файлы для обслуживания команд SQL (соединения, сортировки и другие) создаются в поддиректории pgsql_tmp табличного пространства используемого серверным процессом для создания временных объектов. Имя временного файла pgsql_tmpPPP.NNN, где PPP -  PID серверного процесса, а NNN число, уникальное в пределах одного процесса.

Пример: pg_tblspc/16385/PG_17.1_202501011/pgsql_tmp/pgsql_tmp12345.4

Поскольку временные файлы могут достигать больших размеров, их появление может быть нежелательным в табличных пространствах с постоянно хранимыми данными. Из-за больших объемов записи во временные файлы использование систем хранения на основе магнитных дисков (HDD) возможно будет предпочтительнее массивов хранения на основе чипов памяти (SDD), так как ресурс последних определяется объемом записываемых данных.

Временные объекты

Ограничение на размер временных файлов используемых одним процессом можно установить параметром temp_file_limit. По умолчанию ограничение не установлено. Ограничивается объём временных файлов, которые создаются неявно при выполнении команд. При превышении ограничения команда прервётся. Этот параметр не ограничивает объем файлов явно (командой CREATE TEMPORARY TABLE) созданных временных таблиц.

Временные таблицы могут активно использоваться некоторыми приложениями.

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

Если временная таблица часто очищается командой TRUNCATE, то эта команда (если не использовать расширения и сборки улучшающие работу с временными таблицами) создаёт новый файл в файловой системе с новым именем и обновляет поле relfilenode в таблице pg_class. Файл таблицы системного каталога может вырасти в размерах и автовакуум может отрабатывать чаще. Статистика на временные таблицы также сохраняется в объектах постоянного хранения. При частом создании временных таблиц с большим количеством столбцов порождается много строк в таблице pg_attribute. Таблицы системного каталога могут разрастись до десятков гигабайт. Для таких приложений можно использовать сборки, в которых имеются оптимизации работы с временными таблицами, например, Tantor SE1C.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-client.html#GUC-TEMP-TABLESPACES 

 


Табличные пространства

Табличные пространства

Табличные пространства предназначены для того, чтобы кластер мог располагаться на нескольких устройствах хранения. Устройства хранения монтируются в разные директории. Табличное пространство - это общий объект кластера, представляющий собой ссылку на директорию.

В командах создания объектов можно использовать имя табличного пространства и файлы объектов будут автоматически создаваться в поддиректориях этой директории. На табличные пространства можно давать привилегию USAGE ролям. У табличного пространства есть владелец. Табличное пространство не относится ни к базе данных, ни к схеме, оно относится к кластеру.

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

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

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

Характеристики

После создания в кластере имеется два табличных пространства соответствующие поддиректориям base и global директории PGDATA:

postgres=# \db

 Список табличных пространств

    Имя     | Владелец | Расположение

------------+----------+--------------

 pg_default | postgres |

 pg_global  | postgres |

Табличное пространство pg_default используется по умолчанию для баз данных template1, template0, postgres.
        
Табличное пространство pg_global используется для хранения глобальных таблиц системного каталога и не должно использоваться для хранения пользовательских объектов. В этом табличном пространстве хранятся файлы таблицы pg_tablespace.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/manage-ag-tablespaces.html 

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

Табличные пространства не могут быть «отсоединены» и «присоединены» к другому кластеру базы данных. Они не могут резервироваться по отдельности.

Если табличное пространство будет повреждено (удалён файл, сбой диска) и экземпляр некорректно остановится, то экземпляр не запустится, так как потребуется восстановление по WAL-журналу блоков отсутствующих файлов. Кластер станет полностью недоступным. Поэтому размещать табличные пространства с объектами постоянного хранения на файловой системе неустойчивой к сбоям (в оперативной памяти) нельзя.

Размещать табличные пространства только с временными объектами (временные таблицы) если полностью уверены, что объектов постоянного хранения в них нет на файловой системе в памяти можно. При этом нужно учитывать достаточно ли места под временные таблицы. Если место закончится, то команда вставки строки во временную таблицу выдаст ошибку, файл временной таблицы не удалится. Только команда удаления таблицы сможет удалить файл и освободить место. Команда усечения таблицы может выдать ошибку, так как сначала она создаёт новый файл, а места под него может не быть.

Экземпляр работает с директорией табличного пространства и её содержимым с правами того пользователя из под которого запускаются процессы экземпляра. При создании табличного пространства на уровне файловой системы на директорию должны быть даны привилегии на чтение-запись пользователю postgres операционной системы.

Команды управления

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

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

CREATE TABLESPACE имя [ OWNER роль ] LOCATION 'директория'
[ WITH
( параметр = значение [, ...] ) ]

Директорию табличного пространства располагайте вне PGDATA.

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

ALTER DATABASE база SET TABLESPACE имя;

Переименование табличного пространства:

ALTER TABLESPACE имя RENAME TO имя;

Смена владельца:

ALTER TABLESPACE имя OWNER TO роль;

Удаление табличного пространства (директория на диске не удаляется):

DROP TABLESPACE [ IF EXISTS ] имя;

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-createtablespace.html 

Изменение директории

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

  1. В директории PGDATA/pg_tblspc имеется символическая ссылка с названием значения oid (число) табличного пространства. Эта ссылка указывает на директорию табличного пространства:

ls -al | grep число
число -> /u01/postgres/my_tblspc

  1. Убедитесь, что значение oid соответствует имени табличного пространства, которое вы хотите переместить:

SELECT oid, spcname FROM pg_tablespace;

  1. Остановите экземпляр:

pg_ctl stop

  1. Убедитесь, что экземпляр остановлен:

pg_controldata | grep down
Database cluster state:
shut down

  1. Переместите командой операционной системы или системы хранения директорию табличного пространства в нужное местоположение. При этом можно перемещать директорию внутри той же файловой системы (точки монтирования), либо в любую другую:
    mv /u01/postgres/my_tblspc /u02/postgres
  2. Убедитесь, что пользователю из под которого запускается экземпляр (postgres) даны разрешения на уровне файловой системы на чтение и запись в директорию и ее содержимое
  3. Обновите символическую ссылку PGDATA/pg_tblspc/число, которая указывает на директорию табличного пространства:

ln -fs /u02/postgres/my_tblspc $PGDATA/pg_tblspc/число

  1. Запустите экземпляр: systemctl start tantor-se-server-16
  2. Проверьте, что местоположение поменялось. Например, командой psql \db

Процедура появилась в версии 9.2 PostgreSQL.

Параметры

В текущей версии СУБД Tantor доступны четыре параметра: seq_page_cost, random_page_cost, effective_io_concurrency, maintenance_io_concurrency, которые можно установить на уровне табличного пространства. Установка этих значений влияет на создание планов выполнения команд. Параметры представляют собой весовые коэффициенты, которые используются планировщиком для определения стоимости плана выполнения. Параметры влияют на оценку планировщика какой ресурс «дороже» дисковая подсистема или вычислительные мощности процессоров. Это может быть полезно, если табличное пространство расположено на системе хранения, которая быстрее или медленнее системы хранения, параметры которой установлены в конфигурационных файлах кластера. Одноимённые параметры конфигурации кластера:

seq_page_cost (float) - стоимость чтения блока с диска при последовательном чтении блоков. Файлы, в которых хранятся данные объектов делятся на блоки. Последовательным чтением считается, если блок логически идёт следующим - по смещению от начала файла. Экземпляр не знает о физическом расположении блоков в секторах жестких дисков. По умолчанию 1.0

random_page_cost (float) - стоимость чтения блока с диска при произвольном доступе к блокам файлов. По умолчанию 4.0 Для SSD последовательный и произвольный доступ не отличаются по скорости, то есть random_page_cost можно сделать равным seq_page_cost. Уменьшение random_page_cost относительно seq_page_cost склоняет планировщик к методу доступа "Index Scan" вместо метода доступа "Seq Scan". Одновременное изменение значений обоих параметров меняет оценки стоимости дискового ввода-вывода относительно стоимости использования центральных процессоров.

effective_io_concurrency (integer) - По умолчанию 1. Диапазон от 1 до 1000. Значение 0 отключает асинхронный ввод-вывод (не стоит устанавливать ноль).

Задаёт ограничение на количество блоков, которые каждый серверный процесс будет асинхронно читать-писать. Для систем хранения на основе HDD отправной точкой может быть число жестких дисков. Для SSD можно увеличить до значения, после которого ускорение чтения-записи 8-килобайтными блоками перестаёт существенно расти (например, 64). Также этот параметр учитывается планировщиком при оценке стоимости Bitmap Index Scan. maintenance_io_concurrency (integer) - По умолчанию 10. тот же смысл что и effective_io_concurrency, но используется фоновыми процессами и серверными при выполнении команд поддержки данных. Например, создание индексов, вакуумирование. Его значение должно быть не меньше effective_io_concurrency.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-resource.html 

Работа с файлами журнала

В директории PGDATA/pg_wal создаются файлы журнала. В журнал записываются все изменения в блоках данных файлов кластера (за исключением нежурналируемых и временных объектов). Это значительный объем. По умолчанию значение параметра конфигурации wal_recycle = on. Это означает, что файлы не удаляются, а переименовываются и их тело повторно перезаписывается. Запись в тело файлов идёт потоком от начала файла до конца (если только не переключить на следующий файл функцией pg_switch_wal()). Второй параметр wal_init_zero, значение по умолчанию ноль, что означает: при создании файлов заполнить нулями. При использовании wal_recycle = on файлы повторно используются и нечасто создаются, поэтому дополнительного объема записи немного. При значении wal_init_zero = off при создании файла даётся команда записи последнего байта, чтобы зарезервировать место в файловой системе. Запись байта, а не блока оптимальна, так как операционная система будет использовать блок подходящего ей размера.

Если PGDATA/pg_wal смонтирован на SSD, то стоит следить за тем, чтобы объем хранящихся данных не превышал объем «SLC-кэша» который определяется технологией и алгоритмом контроллера. Для TLC (tripple level cell, 3 бита на ячейку) объем «SLC-кэша» (логический термин, означающий, что контроллер записывает в высокоскоростной первый слой выдерживающий ~100тыс. циклов записи и не успевает переносить данные в другие слои, потому что блоки SSD занятые WAL файлами перезаписываются или очищаются discardом) не может быть больше 1/3. Если превысить, то возникает деградация производительности (зависит от алгоритма работы контроллера) и долговечности. Другими словами, при использовании систем хранения на основе SSD общий объем файлов на точке монтирования PGDATA/pg_wal не должен быть больше примерно 20% от размера. Большой объем свободного места пригодится в случае, если реплика будет испытывать затруднения в приеме журнальных данные и мастер будет их удерживать. Пример ошибки, связанной с нехваткой места. Серверный процесс, который не смог записать в журнал данные прерывается:
LOG:  server process (PID 6353) was terminated by signal 6: Aborted
        
Экземпляр падает:

LOG:  all server processes terminated; reinitializing

После перезапуска экземпляра, если места всё ещё нет:

LOG:  database system was not properly shut down; automatic recovery in progress

FATAL:  could not write to file "pg_wal/xlogtemp.6479": No space left on device

Стоит монтировать файловую систему директории WAL с опцией discard (непрерывный TRIM) вместо службы fstrim, которая оптимальна для файловых систем, хранящих данные которые нечасто меняются. Проверить включён ли DISCARD можно командой линукс: lsblk --discard

Выбор оставить wal_recycle включенным зависит от алгоритма работы контроллера памяти SSD и файловой системы. Параметр wal_init_zero стоит отключить.

Параметр wal_compression по умолчанию отключен позволяет указать алгоритм сжатия, которым будут сжиматься полные образы страниц (full page writes), которые периодически записываются в журнал. Возможные значения pglz, lz4, zstd, on, off. По умолчанию off.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-wal.html 

https://wiki.archlinux.org/title/Solid_state_drive_(Русский) 

https://en.wikipedia.org/wiki/Multi-level_cell 


Слои объектов

Основной слой

Файлы объектов в табличном пространстве делятся на типы, которые в PostgreSQL называют forks (ответвления, слои). Все файлы делятся на блоки размером 8Кб. Минимальный размер файла 8Кб.

Данные объекта хранятся в файлах основного слоя (main fork). Сначала создаётся первый файл основного слоя и увеличивается до 1Гб. Потом создаётся следующий файл и растет до 1Гб и дальше следующие. Максимальный размер таблицы (и любого relation)  32 террабайт (для размера блока 8Кб). Доступа к блокам всех слоёв объектов постоянного хранения происходит через буферный кэш общий для всех процессов кластера. Размер буферного кэша определяется параметром shared_buffers.

Доступ к блокам временных объектов (временных таблиц и индексов на них, последовательностей) происходит через буфер в локальной памяти серверного процесса. Размер буфера определяется параметром temp_buffers. Значение можно поменять в сессии, но только до первого обращения к временному объекту. Файлы временных объектов имеют такой же формат, как у объектов постоянного хранения.

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

Для обычных объектов, префикс имени файла представляет собой число и хранится в столбце relfilenode таблицы pg_class.

Если файл слоя (main,fsm) дорастает до 1Гб создается новый файл с суффиксом ".1". Следующие файлы будут иметь суффикс ".2" и так далее.

Дополнительные слои

Для объектов (кроме хэш-индексов) создаётся слой "fsm" (карта свободного пространства, free space map). В файлах этого слоя хранится структура, отражающая наличие свободного места в блоках основного слоя. Структура организована не в виде списка, а в виде сбалансированного дерева, чтобы процессы могли быстро найти блок для вставки новой записи в блок основного слоя.

Для отношений (кроме индексов) создается слой "vm" (карта видимости и заморозки, visibility map). В файле этого слоя хранится по два бита на блок основного слоя таблицы. Единичка первого бита указывает, что в блоке основного слоя все строки самой последней версии (нет строк которые можно очистить). Этот бит используется при вакуумировании и при методе доступа индексного сканирования (index only scan), к блокам с таким битом они не обращаются. Если во втором бите единичка (бит взведён), это означает, что все строки на этой странице заморожены. Этот бит используется при вакуумировании в режиме заморозки, чтобы пропускать блоки, обработанные в прошлый раз и не менявшиеся с того времени. Файл создается и обновляется процессом, выполняющим вакуумирование. Если файл отсутствует (потерян), он создаётся заново, при этом обрабатываются все блоки основного слоя.

У нежурналируемых таблиц и индексов на них имеется слой "init", состоящий из файла размером один блок (8Кб), который после некорректной остановки экземпляра копируется на место первого файла основного слоя (если есть другие файлы они удаляются) нежурналируемого объекта и объект становится пустым.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/storage.html 

Расположение файлов объектов

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

PGDATA/base/{oid базы данных из pg_database}

Если объект расположен других табличных пространствах (значение столбца reltablespace в pg_class не равно нулю), то файлы объекта располагаются в директории:

PGDATA/pg_tblspc/{reltablespace из pg_class}/{oid базы данных}

Имена файлов объектов начинаются на relfilenode из pg_class.

Для временных объектов имя файла имеет форму tBBB_FFF, где BBB - номер серверного процесса (B - Backend) обслуживающего сессию в которой создан временный объект, FFF - значение relfilenode таблицы pg_class. Значения столбцов relfilenode и oid могут не совпадать, так как команды TRUNCATE, REINDEX, CLUSTER и другие создают файл с новым именем, а oid объекта не меняют. Более того, для некоторых объектов в relfilenode значение ноль.

Для получения местоположения (относительно PGDATA) первого файла основного слоя (main) используется функция pg_relation_filepath(oid).

Для получения префикса имени файлов используется функция pg_relation_filenode(oid).

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

Размеры табличных пространств всего кластера можно посмотреть командой psql \db+

postgres=# \db+

                             Список табличных пространств

    Имя     | Владелец | Расположение | Права доступа | Параметры | Размер | Описание

------------+----------+--------------+---------------+-----------+--------+----------

 pg_default | postgres |              |               |           | 30 MB  |

 pg_global  | postgres |              |               |           | 565 kB |

Также можно посмотреть функцией pg_tablespace_size(oid):

postgres=# SELECT spcname, pg_size_pretty(pg_tablespace_size(oid)) FROM pg_tablespace;

  spcname   | pg_size_pretty

------------+----------------

 pg_default | 30 MB

 pg_global  | 565 kB

Размер баз данных команда l+ или функция pg_database_size(имя):

postgres=# SELECT datname, pg_size_pretty(pg_database_size(datname)) FROM pg_database;

    datname    | pg_size_pretty

---------------+----------------

 postgres      | 7737 kB

 template1     | 7609 kB

 template0     | 7377 kB

 lab01iso88595 | 7537 kB

Функция pg_size_pretty() выводит число в удобном для чтения виде, добавляя символы kB MB GB TB.


Размер объектов

Функции определения размера

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

\dfS *size или запросом
SELECT proname, pg_get_function_arguments(oid) FROM pg_proc WHERE proname LIKE '%size' ORDER BY 1;

 proname                | pg_get_function_arguments

------------------------+---------------------------

 pg_column_size         | "any"

 pg_database_size       | name

 pg_database_size       | oid

 pg_indexes_size        | regclass

 pg_relation_size       | regclass

 pg_relation_size       | regclass, text

 pg_table_size          | regclass

 pg_tablespace_size     | name

 pg_tablespace_size     | oid

 pg_total_relation_size | regclass

(10 строк)

Функции могут выдать размеры отдельных слоёв, общий размер таблицы с TOAST таблицей и индексами или без. Описание какая функция что выдаёт стоит смотреть в разделе документации по функциям для администрирования:

https://docs.tantorlabs.ru/tdb/ru/15_6/se/functions-admin.html 


Перенос объектов

Перемещение объектов

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

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

Второе что важно учитывать это то, что блокировки, устанавливаемые на перемещаемые объекты не дадут возможности работать с объектами даже командам SELECT, так как почти все (кроме запускаемых с опцией CONCURRENTLY) требуют блокировки уровня ACCESS EXCLUSIVE (монопольный режим работы с объектом). Сначала команда перемещения ставится в очередь на получение блокировки и ждёт пока все транзакции и любые одиночные команды закончат работать с объектом, который нужно переместить. Команды SELECT могут работать долго. При этом команда перемещения приводит к ожиданию любых команд, желающих работать с перемещаемым объектом, пока она не получит блокировку и не закончит перемещение.

Команды на перемещение файлов объектов в другое табличное пространство:

ALTER {TABLE | INDEX | MATERIALIZED VIEW } [ IF EXISTS ] имя SET TABLESPACE куда;

ALTER {TABLE | INDEX | MATERIALIZED VIEW } ALL IN TABLESPACE имя [ OWNED BY роль [, ... ] ] SET TABLESPACE куда [ NOWAIT ];

REINDEX [ TABLESPACE куда ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURRENTLY ] имя;

При использовании опции NOWAIT выдаётся ошибка, если команда не может немедленно получить все блокировки на все затрагиваемые объекты.

Существует параметр lock_timeout которым можно задать максимальное время ожидания получения явной или неявной блокировки любой командой. Если с объектом постоянно работают сессии, использование этого параметра может позволить получить блокировку, установив приемлемое время ожидания.

Существует параметр statement_timeout который должен быть больше lock_timeout, так как учитывается время ожидания получения блокировок. Этот параметр задает максимальное время выполнения команды, по достижению которого команда отменяется. Для команд перемещения statement_timeout вряд ли полезен.

Смена схемы и владельца

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

При смене схемы или владельца изменения распространяются на зависимые объекты. Например, вместе с таблицей в другую схему перемещаются созданные на неё индексы, ограничения целостности, последовательности связанные со столбцами.

Владельцем и схемой индекса всегда является и становится владелец и схема таблицы.

Для смены владельца используется команда: ALTER тип_объекта имя OWNER TO роль;

Для смены схемы используется команда: ALTER тип_объекта имя SET SCHEMA схема;

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

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

REASSIGN OWNED BY роль TO роль;

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

DROP OWNED BY имя [CASCADE]; Опцию CASCADE можно использовать чтобы удалить зависимые объекты, принадлежащие другим ролям.


Расширения

pg_repack

Во всех версиях СУБД «Tantor» доступен pg_repack.

pg_repack - это расширение Tantor SE, которое позволяет удалять избыточные данные из таблиц и индексов, а также восстанавливать физический порядок кластеризованных индексов. В отличие от CLUSTER и VACUUM FULL, оно работает онлайн, не накладывая исключающую блокировку на обрабатываемые таблицы. pg_repack также эффективен, и производительность сравнима с использованием CLUSTER напрямую.

Ключевые функции pg_repack:

Только суперпользователи могут использовать утилиту. Целевая таблица должна иметь PRIMARY KEY или по крайней мере, UNIQUE индекс на NOT NULL столбце.

Реорганизация и перемещение объектов pg_repack

В СУБД Tantor всех сборок есть расширение pg_repack с помощью которого можно переместить объекты в другое табличное пространство не устанавливая на время работы монопольную блокировку на объекты. Вместо нее устанавливается блокировка самого щадящего уровня ACCESS SHARE. Такую блокировку устанавливают команды SELECT.

В конце перемещения на короткое время устанавливается монопольная блокировка. Можно установить таймаут на получение этой блокировки параметром --wait-timeout. По истечении таймаута pg_repack может отменить свою операцию если установить параметр --no-kill-backend. По умолчанию же pg_repack отменяет команды, мешающие ему получить блокировку. Если по истечении еще такого же периода времени он всё равно не может получить блокировку, он отсоединит серверные процессы функцией pg_terminate_backend().

Перемещение объектов в другое табличное пространство не основная задача pg_pepack. pg_repack реорганизует файлы объектов, делая структуру более компактной.

Можно задать количество параллельных сессий параметром --jobs, чтобы одновременно перестраивать несколько индексов на одной таблице в режиме полной реорганизации таблицы.

Реорганизация объектов запускается утилитой командной строки pg_repack, но для её работы должно быть установлено расширение в базах данных. Для этого достаточно выполнить команду CREATE EXTENSION pg_repack; в базах данных объекты которых хочется реорганизовать. Базы, в которых не установлено расширение, утилитой игнорируются.

Реорганизацию можно проводить в разных режимах: аналог VACUUM FULL, CLUSTER, REINDEX. На время работы требуется дополнительное свободное место: размер реорганизуемых объектов плюс изменения строк, которые накопятся за время переноса. Весь объем переносимых данных проходит через WAL-журналы.

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

https://docs.tantorlabs.ru/tdb/ru/15_6/be/pg_repack.html 

pg_partman

pg_partman предоставляет набор инструментов для автоматического управления секциями (partitions) таблиц, что улучшает производительность и эффективность работы с большими базами данных.

Разделение таблиц помогает улучшить производительность больших баз данных путем разбиения данных на меньшие, более управляемые части.

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

Преимущества pg_partman:

pgcompacttable

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

Когда таблица в PostgreSQL получает много обновлений, удалений или вставок, она может стать «раздутой» и занимать больше места на диске.

pgcompacttable помогает компактно хранить данные таблицы, удалив неиспользуемые или устаревшие записи, обновляя статистику и упорядочивая физическое размещение данных.

Уменьшение размера файлов pgcompacttable

Утилита pgcompacttable поставлется с СУБД Tantor и находится в директории /opt/tantor/db/16/tools/pgcompacttable.

Утилита уменьшает размер файлов таблиц и индексов без тяжелых блокировок и без резкой нагрузки, влияющей на производительность. Файлы могут увеличиться («bloat», раздуться) в размере из-за большого количества удалённых строк или частых обновлений строк, если автовакуум не мог очищать старые версии строк.

Отличия от pg_repack:

  1. Требуемое для работы свободное место равно размеру самого большого индекса. pg_repack требует двойной размер таблицы и индексов. pgcompacttable обрабатывает содержимое файлов таблиц, индексы перестраиваются по очереди сначала меньший, потом больший по размеру файлов.
  2. Таблицы обрабатываются с задержкой, чтобы предотвратить резкие скачки ввода-вывода и задержки в репликации (если она имеется). pg_repack работает с максимальной скоростью и нагрузкой на файловую систему.
  3. Не может перемещать файлы в другое табличное пространство.
  4. При установленном параметре old_snapshot_threshold не может уменьшать размеры файлов, так же как и VACUUM не выполняет последнюю фазу vacuum_truncate. Это описано в документации к этому параметру.

Установка:

  1. В базах данных нужно установить стандартное расширение pgstattuple: CREATE EXTENSION pgstattuple;
  2. Убрать параметр old_snapshot_threshold: ALTER SYSTEM RESET old_snapshot_threshold;
  3. Установить Perl: apt-get install libdbi-perl libdbd-pg-perl или yum install perl-Time-HiRes perl-DBI perl-DBD-Pg
  4. Установить права на выполнение: chmod 755 -R /opt/tantor/db/16/tools/pgcompacttable

https://docs.tantorlabs.ru/tdb/ru/15_6/se/pgcompacttable.html 

ORC

Добавляет колоночный метод хранения данных с возможностью их сжатия для снижения объема ввода-вывода и достижения высокой производительности.

Подходит для append-only, например time series данных, и витрин корпоративных хранилищ

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

Благодаря колоночной природе pg_columnar повышает производительность за счет чтения только соответствующих данных с диска, и оно может сжимать данные в 6-10 раз для сокращения требований к пространству для архивации данных.

Это расширение использует формат хранения данных, который вдохновлен ORC - форматом оптимизированного колоночного хранилища и предоставляет следующие преимущества:

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

Оптимизатор запросов PostgreSQL использует данные pg_columnar для оценки различных планов запросов и выбора наилучшего.

Расширение ORC: введение

Обычные таблицы (heap tables) хранят данные «построчно» - все поля одной строки физически рядом, потом все поля другой строки, если эти поля «влезают» в один блок данных размером 8Кб. Если строка не «влезает» в блок данных, то используется технология TOAST (The Oversized-Attribute Storage Technique): часть полей переносится в отдельную служебную TOAST-таблицу.

Название этой таблицы не используется в командах SQL и ее использование полностью прозрачно. Можно на каждом столбце таблицы командой ALTER TABLE имя ALTER COLUMN имя SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } установить режим хранения полей этих столбцов.

Например, для режима EXTENDED установленного на столбцах, сначала поля таких столбцов будут сжиматься и если строка со сжатыми полями поместится в блоке, то строка будет сохранена в блоке таблицы. Если же строка не влезет в блок, то часть полей строки будет перенесена в TOAST-таблицу. Для каждого типа данных, который потенциально может не поместиться в блоке (тип данных, «поддерживающий» хранение в TOAST) режим хранения определён по умолчанию (называется «стратегия» хранения полей этого типа) и для большинства типов данных установлена стратегия EXTENDED. Этот режим оптимален, если команды SQL будут обрабатывать поле целиком и значения хорошо сжимаются. Если значения плохо сжимаются или планируется обрабатывать значения полей (например, текстовые поля функциями substr, upper), то возможно более эффективным будет использование режима EXTERNAL. Для типов данных, размер которых невелик и для которых не предусмотрено хранение в TOAST (например, тип DATE) установлена «стратегия» (режим по умолчанию) хранения PLAIN и поменять режим командой ALTER TABLE на другой нельзя, будет выдана ошибка "ERROR:  column data type тип can only have storage PLAIN".

Способ хранения для heap tables допускает сжатие значений отдельных полей. На данных небольшого размера алгоритмы сжатия менее эффективны. Доступ к отдельным столбцам не очень эффективен из-за того, что серверному процессу нужно найти блок в котором хранится часть строки влезающая в блок, затем по каждой строке отдельно выяснить нужно ли обращаться к строкам TOAST-таблицы, читать её блоки и «склеивать» части полей (chunk), которые в ней хранятся в виде строк этой таблицы.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/storage-toast.html 

ORC: общая информация

Идея колоночного способа хранения в том, чтобы снизить трудоёмкость доступа к данным в столбцах путём совместного хранения значений столбцов. При таком способе хранения физически рядом хранятся данные одного столбца целиком или по большому количеству строк. Благодаря тому, что в каждом столбце данные схожи возможно эффективно сжимать данные большими "наборами" строк (chunk). Размер "набора" можно установить на уровне таблицы параметром columnar.chunk_group_row_limit.

Для использования колоночного способа хранения достаточно указать при создании таблицы способ хранения: CREATE TABLE имя (...) USING columnar;

Смена формата хранения командой ALTER TABLE .. SET ACCESS METHOD не реализована. Если реализовать функцию для изменения способа хранения и назвать её, к примеру, alter_table_set_access_method, то этой функции придётся перегружать все данные в новые файлы с блокировкой таблицы. Неблокирующая перегрузка данных является более универсальной и сложной задачей, которая должна реализовываться отдельным расширением и назвать его, к примеру, pg_reorg.

Поскольку хранение данных отличается от обычного, то табличный метод доступа heap не может использоваться и расширение создаёт свой табличный (amtype = 't') метод доступа.


Список методов доступа хранится в таблице системного каталога pg_am:

SELECT * FROM pg_am WHERE amtype = 't';

  oid  |  amname  |             amhandler              | amtype

-------+----------+------------------------------------+--------

     2 | heap     | heap_tableam_handler               | t

 18276 | columnar | columnar_internal.columnar_handler | t

Расширение создаёт схемы columnar и columnar_internal которые использует для хранения своих объектов.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/citus.html 

ORC: особенности использования

Заменяет ли формат columnar формат heap? Нет. Формат heap эффективнее работает с запросами одиночных строк. В базах данных обслуживающих типичные бизнес-задачи (OLTP - online transaction processing) типа ведение продаж, складской и кадровый учет запросы к одиночным строкам встречаются чаще, чем выборка большого количества строк.

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

Формат columnar не поддерживает UPDATE и DELETE. Поддерживаются TRUNCATE, INSERT (в том числе одной строки), COPY. Это основное, что ограничивает применение этого способа хранения.

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

DELETE FROM perf_columnar WHERE id=0;

ERROR:  UPDATE and CTID scans not supported for ColumnarScan

Псевдостолбца CTID в таблицах формата columnar нет.

TOAST с форматом columnar не используется, так как большие значения хранятся внутренне. Параллельное сканирование не реализовано - выборку выполняет один серверный процесс. Поддерживаются индексы типа btree,  hash для быстрой проверки ограничений целостности (PRIMARY KEY, UNIQUE которые поддерживаются), а также в опции секционирования.

Не поддерживаются типы индексов gist, gin, spgist, brin поскольку индексный доступ неэффективен. Расширение совместимо с секционированием таблиц: секционированная таблица может иметь секции использующие и heap и columnar форматы хранения.

ORC: настройки

Последовательная запись в таблицу упорядоченных данных может значительно сократить размер индексов (если они будут созданы) и объем распакованных наборов строк (chunk). Объем распаковываемых данных уменьшается за счет того, что типичным является задавать условие фильтрации по тому столбцу, по которому данные упорядочиваются, а большая часть запрашиваемых данных в случае последовательной вставки хранится совместно. Например, выбираются данные за последний час или сотня последних заказов (номер заказа генерируется последовательностью). Поэтому рекомендуется упорядочивать строки перед их вставкой в таблицу.

В практике часто встречается упорядочивание по времени. Такие данные называют «Time Series», строки вставляются последовательно во времени. Например, последовательная вставка в таблицу показателей измерений какого-нибудь параметра (цены акций, координат транспортного средства) во времени. Сжатие в таких таблицах обычно более эффективно, так как значения соседних полей похоже или даже не меняется (цена акций в последовательных сделках была одинаковой).

Самым эффективным методом сжатия данных является zstd.

При чтении небольших объемов данных использование индексов может оказаться более эффективным.

Расширение имеет параметры конфигурации:

columnar.chunk_group_row_limit, columnar.compression_level, columnar.stripe_row_limit, columnar.compression, columnar.planner_debug_level

Можно устанавливать параметры на уровне таблиц.

Параметры можно посмотреть в представлении options схемы columnar.

SELECT * FROM columnar.options;

-[ RECORD 1 ]---------+--------------

relation              | perf_columnar

chunk_group_row_limit | 10000

stripe_row_limit      | 150000

compression           | zstd

compression_level     | 3

Раздел 5. Журналирование

Журнал событий

Конфигурирование

Определение

Журнал сообщений (или лог) PostgreSQL является важным инструментом для отслеживания и анализа деятельности системы баз данных.

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

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

Параметры

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

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

Вот несколько из них:

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

Запись show log_line_prefix; в PostgreSQL используется для отображения текущего значения параметра log_line_prefix.

В данном конкретном примере:

show log_line_prefix;

   log_line_prefix      

------------------------

%m [%p:%v] [%d] %r %a  

(1 row)

%m - уровень сообщения (DEBUG5, DEBUG4, INFO, WARNING, ERROR, и так далее).

[%p:%v] - идентификатор процесса PostgreSQL и номер версии протокола.

[%d]- имя базы данных.

%r - идентификатор транзакции.

%a - IP-адрес и порт клиента.

Таким образом, префикс будет включать уровень сообщения, идентификатор процесса и версию протокола, имя базы данных, идентификатор транзакции, а также IP-адрес и порт клиента для каждой строки в логе. Это делает логи более информативными и удобными для анализа в контексте деятельности PostgreSQL.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-logging.html#GUC-LOG-LINE-PREFIX

Расположение

Давайте выясним, где хранится журнал сообщений сервера и как он называется.

Для этого необходимо рассмотреть два ключевых параметра:

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-logging.html#GUC-LOG-LINE-PREFIX 

Приемники сообщений

PostgreSQL обеспечивает различные методы регистрации сообщений сервера.

Логи в формате JSON обеспечивают структурированный вывод, что упрощает обработку данных с использованием инструментов обработки JSON.

syslog:

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

eventlog (Windows)- на операционной системе Windows доступен специфический метод записи логов в Windows Event Log. Это может быть полезно для интеграции с инфраструктурой мониторинга Windows.

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

Например:

log_destination = 'stderr,csvlog'

В данном случае сообщения будут регистрироваться и в stderr, и в формате CSV. Параметр log_destination позволяет гибко настраивать распределение логов в соответствии с требованиями системы мониторинга и анализа.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-logging.html#GUC-LOG-DESTINATION

Ротация

Для применения ротации журнала в PostgreSQL, вы можете использовать параметры log_rotation_age и log_rotation_size в файле конфигурации postgresql.conf.

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

Например, чтобы установить ротацию каждый час, вы можете указать:

log_rotation_age = 60

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

Например, чтобы установить ротацию при достижении файла размера 10 МБ, вы можете указать:

log_rotation_size = 10MB

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

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

Чтение сообщений

Чтение сообщений сервера в PostgreSQL рекомендуется осуществлять через просмотр лог-файлов, куда записываются соответствующие сообщения.

Здесь несколько способов и инструментов для этого:

Вы можете использовать текстовые редакторы, команды tail или cat для просмотра содержимого лог-файлов.

Установка pgBadger и его использование позволяют легко просматривать и анализировать логи с дополнительной статистикой и графиками.

Эти инструменты обеспечивают удобный интерфейс для поиска, фильтрации и анализа логов. Централизованным сбором так же занимается Платформа «Tantor».

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

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


Форматы

csv, json

В PostgreSQL, наряду с текстовым форматом сообщения в журнале могут быть записаны в различных форматах, таких как CSV (Comma-Separated Values) и JSON (JavaScript Object Notation).

Вот краткое описание каждого формата:

Пример записи:

2022-03-01 12:34:56.789 EDT,LOG,postgres,user1,localhost,,,select * from table;

Как включить:

log_destination = 'csvlog'

Как включить:

log_destination = 'jsonlog'

{

  "timestamp": "2022-03-01T12:34:56.789 EDT",

  "log_level": "LOG",

  "user": "user1",

  "host": "localhost",

  "database": "postgres",

  "statement": "select * from table"

}

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


Процесс logging_collector

Гарантия доставки сообщения

logging_collector - параметр конфигурации PostgreSQL, который управляет активацией сборщика журналов. Сборщик журналов - это фоновый процесс, который отслеживает и захватывает сообщения журнала, отправленные в стандартный поток ошибок (stderr), и перенаправляет их в файлы журналов.

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

Параметр logging_collector может быть установлен только при запуске сервера. Это означает, что для активации или деактивации сборщика журналов необходимо изменить параметр в конфигурационном файле (postgresql.conf) и перезапустить PostgreSQL. Также можно задать в командной строке при запуске сервера.

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-logging.html#GUC-LOGGING-COLLECTOR


Раздел 6. Безопасность

Ролевая модель безопасности

Роли

Роль

В PostgreSQL роль (role) представляет собой концепцию, аналогичную пользователям или группам пользователей в других системах управления базами данных (СУБД). Роль в PostgreSQL определяет права доступа к базе данных и объектам в ней, таким как таблицы, представления, процедуры и другие объекты. Роли могут иметь различные привилегии, такие как создание, изменение или удаление объектов базы данных, а также права на выполнение определенных операций.

Роль - это объект в базе данных, создаваемый на уровне кластера. Это означает, что после создания роль становится видимой в любой базе данных в этом кластере.

Роли в PostgreSQL предоставляют гибкий и мощный механизм управления доступом к данным и объектам базы данных.

В PostgreSQL роль пользователя (User Role) не имеет прямой связи с внешним пользователем операционной системы (ОС). То есть, создание роли пользователя в PostgreSQL не предполагает автоматического создания соответствующей учетной записи в ОС, и наоборот. Роли пользователей в PostgreSQL управляются в рамках самой базы данных и не имеют прямого отображения на учетные записи ОС.

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

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

Для создания и удаления роли в PostgreSQL вы можете использовать SQL-команды CREATE ROLE и DROP ROLE.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/database-roles.html

Атрибуты

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

SUPERUSER - роль с этим атрибутом обладает всеми привилегиями в базе данных и может выполнять любые операции.

CREATEDB - роль с этим атрибутом может создавать новые базы данных.

CREATEROLE - роль с этим атрибутом может создавать новые роли пользователей.

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

REPLICATION - роль с этим атрибутом может участвовать в процессе репликации данных между серверами баз данных.

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

Как вариант атрибуты - это свойства объекта роль.

Для установки атрибутов роли в PostgreSQL вы можете использовать команду ALTER ROLE с указанием имени роли и необходимого атрибута.

ALTER ROLE имя_роли WITH атрибут;

https://docs.tantorlabs.ru/tdb/ru/15_6/se/role-attributes.html

Групповая роль

Групповая роль в PostgreSQL - это роль, которая объединяет одну или несколько других ролей вместе. Она позволяет управлять правами доступа и привилегиями для нескольких пользователей одновременно, обеспечивая более удобное и гибкое управление безопасностью базы данных.

Добавлять другие роли в эту группу с помощью команды GRANT. Это делается путем назначения роли членом другой роли:

GRANT имя_групповой_роли TO имя_роли;

Отзыв делается командой REVOKE

REVOKE имя_групповой_роли  FROM имя_роли;

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

SET ROLE имя_роли.

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/role-membership.html 

Предопределенные роли

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

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

В PostgreSQL существуют роли, такие как pg_monitor, pg_read_all_settings, pg_read_all_stats и pg_stat_scan_tables, которые предназначены для облегчения настройки роли администратора для мониторинга сервера баз данных.

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

Роль pg_database_owner является владельцем текущей базы данных.

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

pg_database_owner не может быть членом другой роли и не имеет неявных членов.

Роль pg_signal_backend предназначена для разрешения отправки сигналов другим процессам бэкенда.

Это позволяет администраторам разрешать доверенным ролям отправлять сигналы для отмены запросов или завершения сессий.

Роли pg_read_server_files, pg_write_server_files и pg_execute_server_program предоставляют доступ к файлам и возможность запуска программ на сервере базы данных от имени пользователя, от имени которого работает база данных.

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

Предостережение по использованию ролей:

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/predefined-roles.html

public

Роль "public" включает в себя все остальные роли по умолчанию. Это означает, что если вы назначаете какие-либо привилегии для роли "public", то эти привилегии будут распространяться на всех пользователей и роли в базе данных, которые не имеют явно определенных прав доступа.

Роль "public" является глобальной ролью по умолчанию для всех пользователей, если для них не указаны специальные права доступа. Это обеспечивает простоту и единообразие в управлении доступом, поскольку права, назначенные для "public", применяются ко всем объектам базы данных для всех пользователей, если не определены другие специфические права.

Таким образом, роль "public" является ключевым элементом в обеспечении открытого или общего доступа к объектам базы данных по умолчанию, если не требуется явное ограничение доступа для конкретных пользователей или ролей.

Хотя роль "public" обеспечивает удобное и простое управление доступом к объектам базы данных, следует помнить о потенциальных рисках безопасности. Предоставление привилегий через роль "public" может привести к широкому доступу к данным и функциональности, что может повысить риск утечки информации или злоупотребления привилегиями.

Отзыв привилегий у роли "public" может быть сложным и потребует тщательного тестирования, чтобы убедиться, что изменения не повредят функциональность системы и не нарушают доступ пользователей, которым привилегии были предоставлены. Поэтому рекомендуется использовать принцип минимальных привилегий и явно назначать права доступа только тем пользователям и ролям, которым они действительно необходимы.


Привилегии

Привилегии

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

Эти привилегии распространяются на различные объекты базы данных, включая таблицы, представления, подпрограммы (например, функции и хранимые процедуры), а также на другие элементы, такие как базы данных и схемы.

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

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/ddl-priv.html#id1

Привилегии таблицы, представления

У таблицы в PostgreSQL могут быть следующие привилегии:

SELECT - разрешает чтение данных из таблицы.

INSERT - разрешает добавление новых строк в таблицу.

UPDATE - разрешает изменение существующих строк в таблице.

DELETE - разрешает удаление строк из таблицы.

REFERENCES - разрешает ссылаться на таблицу внешним ключом.

TRIGGER - разрешает создание триггеров на таблицу.

TRUNCATE - разрешает очистку (удаление всех строк) таблицы.

На уровне столбца таблицы можно назначить привилегии SELECT, INSERT, UPDATE, REFERENCE, что расширяет возможности ролевой модели безопасности

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

SELECT - разрешает чтение данных из представления.

TRIGGER - разрешает создание триггеров на представление.

Привилегии БД, схемы

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

Для базы данных:

CONNECT - разрешает подключение к базе данных.

CREATE - разрешает создание новых объектов в базе данных.

TEMPORARY - разрешает создание временных объектов в базе данных.

Для схемы:

CREATE - разрешает создание новых объектов в схеме.

USAGE - разрешает использование объектов в схеме.

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

Привилегии подпрограмм

Опция контекста безопасности имеет два возможных значения:

SECURITY DEFINER - когда подпрограмма (функция, процедура или представление) запускается с опцией SECURITY DEFINER, она выполняется с привилегиями владельца объекта, а не пользователя, который вызывает эту подпрограмму. Это позволяет подпрограмме иметь доступ к объектам базы данных и выполнять операции от имени владельца, что может быть полезно для выполнения привилегированных операций.

SECURITY INVOKER - когда подпрограмма запускается с опцией SECURITY INVOKER (по умолчанию), она выполняется с привилегиями пользователя, который вызывает эту подпрограмму. Это означает, что подпрограмма выполняется с правами доступа вызывающего пользователя, а не с привилегиями владельца объекта.

Использование SECURITY DEFINER следует рассматривать с осторожностью, так как это может представлять потенциальные угрозы безопасности, особенно если неправильно настроить права доступа к подпрограмме или контроль за ее выполнением.

Привилегии роли public

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

Для баз данных:

CONNECT - это разрешает пользователям подключаться к данной базе данных.

TEMPORARY - позволяет создавать временные таблицы в этой базе данных.

Для схемы public:

CREATE - это дает возможность пользователям создавать новые объекты (такие как таблицы, представления и прочие) в схеме public.

USAGE - обеспечивает доступ к существующим объектам в схеме public.

Для системных схем (pg_catalog и information_schema):

USAGE - предоставляет возможность просматривать объекты в этих системных схемах, такие как таблицы, представления и функции.

Для подпрограмм (функций и процедур):

EXECUTE - это дает право на выполнение функций и процедур.

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

Привилегии по умолчанию

ALTER DEFAULT PRIVILEGES - команда в SQL, используемая в PostgreSQL для изменения привилегий по умолчанию, которые будут автоматически назначены к определенным типам объектов базы данных, создаваемым в будущем. Позволяет администраторам базы данных настроить стандартные права доступа для новых объектов, что обеспечивает более гибкое управление безопасностью данных в системе.

Назначение привилегий по умолчанию:

ALTER DEFAULT PRIVILEGES позволяет установить привилегии, которые будут применяться к объектам, созданным в будущем.

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

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

По умолчанию привилегии для каждого типа объекта обычно предоставляют все разрешения, которые можно предоставить владельцу объекта, и могут также предоставлять некоторые привилегии для PUBLIC. Однако это поведение можно изменить, изменив глобальные привилегии по умолчанию с помощью ALTER DEFAULT PRIVILEGES.

Все привилегии по умолчанию, указанные для схемы, добавляются к глобальным привилегиям по умолчанию для конкретного типа объекта. Это означает, что отзыв привилегий REVOKE для схемы имеет смысл только для отмены эффектов предыдущего предоставления привилегий GRANT для схемы.

Предположим, вы хотите автоматически предоставлять пользователям привилегию на SELECT для всех таблиц, созданных в будущем в схеме public. Для этого вы можете использовать следующую команду:

ALTER DEFAULT PRIVILEGES IN SCHEMA public

    GRANT SELECT ON TABLES TO PUBLIC;

Эта команда устанавливает привилегию SELECT по умолчанию для всех таблиц, созданных в будущем в схеме public, для роли PUBLIC, что позволит всем пользователям выполнять операцию SELECT на новых таблицах без необходимости явного назначения привилегий на каждую таблицу.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-alterdefaultprivileges.html#alter-default-privileges


Политика защиты строк

Определение

Политика безопасности строк (Row-level security policy) - это механизм в PostgreSQL, который позволяет определять правила доступа к отдельным строкам данных в таблицах на основе различных условий. Она расширяет стандартные системы управления доступом, позволяя ограничивать доступ к строкам данных в зависимости от их содержимого или контекста запроса.

Основные аспекты политики безопасности строк:

Установка - политика безопасности строк устанавливается для конкретной таблицы с помощью команды ALTER TABLE ... ENABLE ROW LEVEL SECURITY.

Применение - политика определяет, какие операции могут быть выполнены с каждой строкой данных, включая SELECT, INSERT, UPDATE и DELETE.

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

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

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

Управление - создание, изменение и удаление политик осуществляется с помощью команд CREATE POLICY, ALTER POLICY и DROP POLICY.

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/ddl-rowsecurity.html

Разрешающие и ограничивающие политики

Каждая политика безопасности строк в PostgreSQL имеет уникальное имя и применяется к конкретной таблице. Это позволяет определять несколько политик для одной таблицы с различными правилами доступа. Поскольку политики применяются на уровне запроса к данным, они объединяются с использованием операторов OR или AND, в зависимости от их характера.

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

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

Разрешающие политики - предоставляют доступ к строкам данных в таблице. Когда применяются несколько разрешающих политик к запросу, строки данных, соответствующие хотя бы одной из политик, будут доступны пользователю. При объединении разрешающих политик используется логический оператор OR, что означает, что если хотя бы одна из политик разрешает доступ к строке, она будет доступна для пользователя.

Ограничивающие политики - ограничивают доступ к строкам данных в таблице. Если применяются несколько ограничивающих политик к запросу, строки данных, которые соответствуют всем условиям ограничений, будут доступны пользователю. При объединении ограничивающих политик используется логический оператор AND, что означает, что строка данных будет доступна только в том случае, если она удовлетворяет всем условиям всех примененных политик.

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

credcheck

Модуль credcheck - доступен во всех версиях «Tantor.»

Расширение credcheck предоставляет несколько общих проверок учетных данных, которые выполняются при создании пользователя, при смене пароля и переименовании пользователя. Используя это расширение, можно определить набор правил:

Это расширение разработано на основе хука check_password_hook в PostgreSQL.

credcheck предоставляет все проверки в виде настраиваемых параметров. Настройки по умолчанию не предусматривают сложных проверок и пытаются разрешить большую часть учетных данных. Используя команду указанную на слайде можно применить новые настройки для проверки учетных данных. Настройки могут быть изменены только суперпользователем.

pgAudit

Модуль pgAudit - доступен во всех версиях «Tantor».

Расширение pgAudit предоставляет детальное аудиторское ведение журнала сессий и/или объектов через стандартное средство ведения логов PostgreSQL.

Обеспечивает подробное журналирование сессий и/или объектов через стандартный механизм регистрации Tantor DBMS. Целью pgAudit является предоставление пользователям Tantor DBMS возможности создания журналов аудита, которые часто требуются для соответствия правилам правительства, финансовым или ISO сертификациям. Информация, собранная pgAudit, правильно называется «журналом регистрации» или «журналом аудита».

pgauditlogtofile

Модуль pgauditlogtofile - доступен во всех версиях «Tantor». Дополнение к pgAudit, которое перенаправляет строки аудита в отдельный файл, вместо использования журналирования сервера PostgreSQL. Это позволяет нам иметь файл аудита, который можно легко ротировать, не загрязняя журналы сервера этими сообщениями. Журналы аудита в системах с высокой нагрузкой могут очень быстро расти. Это расширение позволяет автоматически ротировать файлы на основе заданного количества минут.


Подключение и аутентификация

Задачи авторизации

Аутентификация, идентификация, авторизация

Прежде чем разберемся, как устроено подключение к СУБД PostgreSQL, более внимательно рассмотрим три задачи, а именно - аутентификация, идентификация, авторизация

1. Идентификация в PostgreSQL.

В PostgreSQL идентификация обычно осуществляется с помощью уникальных имен пользователей. Каждый пользователь в базе данных имеет свой собственный уникальный идентификатор, который используется для связывания с соответствующими разрешениями и правами доступа к базам данных и их объектам. Идентификация также может включать другие атрибуты, такие как пароль или метод аутентификации операционной системы, чтобы подтвердить личность пользователя.

2. Аутентификация в PostgreSQL.

В PostgreSQL аутентификация может осуществляться различными способами, включая использование паролей, методов аутентификации операционной системы, а также других методов, таких как аутентификация GSSAPI (Generic Security Services Application Programming Interface). При аутентификации пользователь предоставляет учетные данные, которые затем сравниваются с данными, хранящимися в базе данных, для проверки их подлинности.

3. Авторизация в PostgreSQL.

Авторизация в PostgreSQL осуществляется с помощью назначения ролей пользователям и предоставления соответствующих разрешений на выполнение определенных операций с базами данных, таблицами, представлениями и другими объектами. После того как пользователь успешно прошел процесс аутентификациии, система определяет его права доступа на основе назначенных ему ролей и правил авторизации.


Конфигурирование

Файлы конфигурации. Где найти?

Файл pg_hba.conf является одним из основных файлов конфигурации PostgreSQL. Он используется для определения правил аутентификации, которые управляют тем, как клиенты могут подключаться к серверу PostgreSQL и как их идентификация будет проверяться. Этот файл определяет различные параметры аутентификации, такие как методы аутентификации, адреса клиентов, базы данных, для которых правило действительно, и пользователи, которые могут использовать это правило.

Поскольку файл pg_hba.conf играет ключевую роль в настройке безопасности и аутентификации в PostgreSQL, внесение изменений в этот файл должно производиться осторожно, чтобы избежать уязвимостей и обеспечить безопасность базы данных.

postgres=# show hba_file;

                     hba_file                      

---------------------------------------------------

 /var/lib/postgresql/tantor-se-16/data/pg_hba.conf

Команда SHOW hba_file; в PostgreSQL выводит путь к файлу pg_hba.conf, который используется для настройки правил аутентификации в PostgreSQL. В вашем случае путь к файлу pg_hba.conf указан как /var/lib/postgresql/tantor-se-16/data/pg_hba.conf.

Таким образом, файл pg_hba.conf для вашего экземпляра PostgreSQL находится в указанном пути. Вы можете открыть этот файл с помощью текстового редактора для просмотра и изменения правил аутентификации, определенных в нем.


pg_hba

Чтение файла конфигурации

postgres=# select rule_number, type, database, user_name, auth_method from  pg_hba_file_rules();

 rule_number | type  |   database    | user_name  | auth_method

-------------+-------+---------------+------------+-------------

           1 | local | {all}         | {pma_user} | md5

           2 | local | {all}         | {all}      | trust

           3 | host  | {all}         | {all}      | trust

           4 | host  | {all}         | {all}      | trust

           5 | local | {replication} | {all}      | trust

           6 | host  | {replication} | {all}      | trust

           7 | host  | {replication} | {all}      | trust

Этот вывод показывает содержимое файла pg_hba.conf для вашего экземпляра PostgreSQL. Давайте разберем каждую строку:

rule_number (номер правила) - это порядковый номер правила в файле pg_hba.conf.

type (тип соединения) - определяет тип подключения, для которого действует данное правило. В вашем случае есть два типа: local (для локальных соединений) и host (для удаленных соединений).

database (база данных) - указывает, для каких баз данных действует данное правило. {all} указывает, что правило применяется ко всем базам данных.

user_name (имя пользователя) - определяет, для каких пользователей действует данное правило. {all} указывает, что правило применяется ко всем пользователям. В случае строк типа local указано конкретное имя пользователя, например, {pma_user}.

auth_method (метод аутентификации) - указывает метод аутентификации, который будет использоваться для проверки подлинности клиента. Например, md5 используется для парольной аутентификации, а trust означает, что подключение разрешено без проверки пароля.

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

Также в представлении есть и другие поля file_name (Имя файла) - это имя файла pg_hba.conf, в котором определено данное правило.

line_number (номер строки) - это номер строки в файле pg_hba.conf, где определено данное правило.

address (адрес клиента) - это IP-адрес или доменное имя клиента, для которого применяется правило. Обычно используется в правилах типа host.

netmask (маска подсети) - это маска подсети, которая определяет диапазон IP-адресов, для которых действует правило. Обычно используется в правилах типа host.

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

error (ошибка) - это текстовое описание любой ошибки, возникшей при обработке данного правила.

Поля аутентификации

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

Разбор полей правил аутентификации в файле pg_hba.conf:

type (Тип соединения):

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

database (база данных):

user_name (Имя пользователя):

address (Адрес клиента):

Заключение:

Понимание каждого из этих полей помогает администраторам настраивать безопасность и функциональность своей базы данных в соответствии с требованиями безопасности и доступа к данным. Правильная настройка правил аутентификации в файле pg_hba.conf является важным шагом для обеспечения безопасности и надежности PostgreSQL сервера.

Протоколы аутентификации внутренние

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

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

reject (отказ) - отклоняет все попытки подключения к базе данных без каких-либо дополнительных проверок или запросов к пользователям, предназначенным для временного отключения доступа или предотвращения всех попыток подключения.

md5 (MD5-хеширование пароля) - подобно методу пароля, пользователь должен предоставить пароль для аутентификации, однако он передается в зашифрованном виде, используя алгоритм MD5 для хеширования пароля. Это более безопасный метод, чем простое хранение пароля в зашифрованном виде.

scram-sha-256 (Salted Challenge Response Authentication Mechanism) - этот метод аутентификации предлагает более безопасное и современное решение, чем md5. Он использует алгоритм HMAC (Hash-based Message Authentication Code) для аутентификации, который основан на комбинации хэширования SHA-256 и случайного набора символов (соль).

ident - при использовании этого метода PostgreSQL отправляет запрос на сервер идентификации (обычно это служба ident) на клиентском компьютере для проверки, есть ли у пользователя разрешение на подключение к базе данных. Этот метод часто используется в ситуациях, где необходимо подтверждение идентичности пользователя на удаленной системе.

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

Протоколы аутентификации внешние

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

peer (взаимный) - метод аутентификации используется для локальных подключений к серверу PostgreSQL на основе операционной системы. PostgreSQL проверяет идентификатор пользователя, под которым запущен клиент, и пытается аутентифицировать его как базу данных пользователя с тем же именем. Это предполагает, что имена пользователей на уровне ОС и в PostgreSQL совпадают.

LDAP (Lightweight Directory Access Protocol) - метод аутентификации LDAP используется для проверки подлинности пользователей с помощью централизованного сервера каталогов, который поддерживает протокол LDAP. PostgreSQL может взаимодействовать с сервером LDAP для проверки имени пользователя и пароля перед предоставлением доступа к базе данных.

Kerberos - протокол аутентификации Kerberos обеспечивает безопасную аутентификацию на основе обмена ключами между клиентом и сервером. При использовании этого метода PostgreSQL взаимодействует с сервером Kerberos для проверки подлинности пользователей перед разрешением доступа к базе данных.

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


pg_ident

Сопоставление внешнего пользователя и роли

pg_ident - это файл идентификации PostgreSQL, который используется для сопоставления внешних имен пользователей с именами пользователей PostgreSQL. Этот файл позволяет настраивать соответствие между внешними именами пользователей, которые поступают от клиентов, и именами пользователей PostgreSQL, которые используются для аутентификации и авторизации на сервере баз данных.

В основном pg_ident используется в двух основных случаях:

Интеграция с внешними системами аутентификации:

Когда PostgreSQL используется в окружениях, где аутентификация пользователей управляется внешними системами, такими как операционная система или централизованные службы аутентификации (например, LDAP или Kerberos), pg_ident позволяет сопоставить идентификационные имена, используемые этими системами, с именами пользователей PostgreSQL.

Переименование пользователей:

pg_ident также может использоваться для переименования пользователей PostgreSQL для улучшения безопасности или сокрытия реальных имен пользователей от внешних клиентов. Например, вы можете использовать pg_ident для сопоставления внешнего имени "webuser" с реальным именем пользователя PostgreSQL "app_user".

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

Пример

Давайте подробно рассмотрим ваш пример.

Файл pg_hba.conf:

# TYPE  DATABASE        USER            ADDRESS                 METHOD

local   all             all                                     ident    map=map1


        Эта строка в файле
pg_hba.conf означает, что для всех баз данных и всех пользователей, пытающихся подключиться локально (через сокеты UNIX), будет использоваться метод аутентификации "ident" с использованием маппинга map1.


Файл pg_ident.conf:

# MAPNAME       SYSTEM-USERNAME         PG-USERNAME

map1           astra                  user1

Эта строка в файле pg_ident.conf определяет маппинг map1, который говорит PostgreSQL, что внешний пользователь "astra" должен быть аутентифицирован как пользователь PostgreSQL "user1".

Теперь, когда локальный пользователь "astra" пытается подключиться к PostgreSQL, сервер PostgreSQL смотрит на файл pg_ident.conf, чтобы узнать, какой пользователь PostgreSQL должен быть сопоставлен с внешним пользователем "astra". В данном случае, внешнее имя пользователя "astra" будет сопоставлено с пользователем PostgreSQL "user1".

Таким образом, локальный пользователь "astra" сможет подключиться к базе данных только как пользователь PostgreSQL "user1".

 pg_anon

Во всех версиях СУБД «Tantor» доступен pg_anon.

pg_anon - это автономная программа, написанная на Python, предназначенная для работы с PostgreSQL (начиная с версии 9.6 и выше), которая выполняет следующие задачи:

Раздел 7. Резервное копирование

Физическое копирование

Виды резервных копий

Виды резервных копий

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

Файлы могут теряться и повреждаться по разным причинам. Например, злоумышленник или программа («компьютерный вирус») могут стереть файлы кластера. Зеркалирование дисков в этом случае не поможет. В СУБД Tantor есть много способов резервирования. Самое оптимальное с точки зрения простоты, стоимости, отказоустойчивости для типичного кластера это использовать физическую репликацию, которую мы рассмотрим в отдельной главе.

Резервные копии («бэкапы») могут быть:

Для горячих физических резервных копий понятие согласованного состояния (consistent state) означает, что на копию наложены журнальные данные на момент окончания резервирования. Холодные резервные копии если экземпляр был остановлен корректно считаются согласованными. Горячую резервную копию можно согласовать накатив на неё журнальные файлы (WAL-журналы) до момента окончания резервирования.

В любом случае при запуске на согласованной копии будет искаться журнальный файл, содержащий запись о контрольной точке, на которую указывает управляющий файл (или файл backup_label если он есть). Если файл журнала отсутствует, экземпляр не запустится. Согласованность лишь ускоряет запуск экземпляра.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/backup-file.html 

Инкрементальные копии

Также резервирование может быть инкрементальным. В стандартной поставке СУБД Tantor имеется утилита резервирования pg_basebackup, она не поддерживает инкрементальное резервирование. Есть расширение pg_probackup, которое поддерживает инкрементальное резервирование и восстановление. Также есть клиентская программа WAL-G которая поддерживает создание «дельта-копий» (дельта от слова разница, дифференциальные копии то же самое что инкрементальные). Инкрементальное резервирование оправдано в случае когда обычное резервирование длится долгое время или создаёт повышенную нагрузку на ввод-вывод (чтение и запись файлов, ресурсы «железа»).

Долгим временем может считаться, например, если экземпляр ночью испытывает небольшую нагрузку, то резервирование не успевает завершиться за ночь. Логика инкрементального резервирования в том, что создается один раз полная копия всех файлов данных и исходя из того, что за сутки (или желаемые интервалы между резервированием) успевает измениться небольшая часть блоков файлов данных, то достаточно зарезервировать только изменившиеся блоки. Объем будет небольшой. Чтобы резервирование шло быстро и не читались все блоки файлов данных (а это половина времени резервирования) должно использоваться расширение, которое будет на работающем экземпляре отслеживать изменения в блоках данных. Если полученный бэкап небольшого размера можно наложить на полный бэкап, это называется инкрементально-обновляемая резервная копия. Делается один раз полный бэкап на что тратится время, а потом раз в сутки (или другой периодичностью) делается инкрементальный бэкап, накладывается на полный и после этого удаляется. Периодичность выбирается исходя из того какой объем журнальных файлов за это время генерирует кластер.

Объем журнальных файлов не зависит от объема кластера. После создания любой (и инкрементальной) копии журнальные файлы можно удалять, тем самым освобождая место, а также ускоряя восстановление если оно потребуется. Ускорение достигается за счет того, что не придется накатывать журналы, объем которых может быть значительным.

Недостаток инкрементального резервирования - большая сложность процедур. Чем больше сложность, тем больше вероятность ошибиться в том числе в процессе непредвиденного сбоя и необходимости выполнять процедуру восстановления.

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

Что резервировать

В кластере имеются:

  1. Файлы данных - бинарные файлы с размером блока 8Кб. В них содержатся данные объектов базы данных, системного каталога и служебные файлы (управляющий файл, файлы XLOG и другие). Сюда же относятся и директории, в которых располагаются файлы и символические ссылки.
  2. WAL-журнал или «журнал предзаписи» или просто «журнал». Слово «журнал» может использоваться и для обозначения текстовых файлов сообщений экземпляра. В в этой главе будем использовать его для обозначения журнала предзаписи. Он состоит из файлов по умолчанию имеющих размер 16Мб. В журнал записываются изменения в блоках файлов данных и с частотой контрольных точек могут записываться полные образы изменившихся с момента предыдущей контрольной точки блоков данных.
  3. Текстовые файлы параметров и другие файлы и директории, находящиеся в PGDATA не распознаваемые утилитами резервирования как временные. Резервируются для удобства вместе с файлами данных.
  4. Временные файлы. Их можно не резервировать, так как их срок жизни не дольше сессии, после чего они могут быть удалены. Если утилита резервирования может распознать такие файлы, она их в бэкап не включает.

Логика резервирования в следующем. Делается копия файлов данных и других файлов. Это можно делать утилитами операционной системы, но это неудобно так как надо предусмотреть выполнение контрольной точки или получения о ней данных. Обычно используют утилиту pg_basebackup или утилиты расширений, которые автоматизируют как резервирование, так и восстановление. Дальше копятся или передаются в безопасное место журналы, создаваемые с момента завершения контрольной точки перед резервированием и до самого последнего момента, пока работает экземпляр (если хочется восстановиться до последнего момента, а это обычно необходимое требование для сколько-нибудь важных данных). Таким образом создаются «бэкапы файлов кластера» и «архив журналов».

https://docs.tantorlabs.ru/tdb/ru/15_6/se/continuous-archiving.html 

Архитектура резервирования и восстановления

Процедура восстановления

  1. Обнаружение повреждения. Экземпляр при этом может быть аварийно остановлен и попытка запуска не удастся. Либо продолжать работать, но выдавать ошибки при доступе к части данных. Если экземпляр не остановился, его нужно будет остановить в аварийном режиме, так как вряд ли он остановится корректно.
  2. Восстановить из бэкапа всё что в нём есть. Если размер кластера большой, можно пытаться восстанавливать только те файлы, которые отличаются. Гарантию даст только подсчет контрольных сумм каждого файла и их сравнение. Если утилита восстановления имеет такие режимы можно их использовать. Ручное использование например rsync (в режиме подсчета контрольных сумм) может увеличить время восстановления, та как к нему добавляется «think time» - время на планирование и ввод команд восстановления. Оптимально иметь командные файлы и простые инструкции на случай сбоев, это уменьшит время восстановления за счет устранения времени на раздумья и вероятные ошибки.
  3. Накатить (наложить, применить) журнальные файлы. Файлы применяются в строгом порядке их создания экземпляром, пропуски (gap) - отсутствие файла или повреждение блоков (они распознаются, так как блоки журналов защищены контрольными суммами) в его теле критичны - перейти через них нельзя. Поэтому журналы можно называть «цепочкой» журнальных файлов (WAL сегментов), так как повреждения звена цепочки ее разрывает. Есть техники восстановления с пропусками, но не стоит на них полагаться. Если пропусков нет, но запись не может быть применена к файлу данных (файл отсутствует), то накат также останавливается. Записи журналов применяются к блокам данных в строгом порядке. При применении проверяется, что к блоку данных может быть применена запись. В журналах по умолчанию присутствуют полные образы изменившихся блоков (full_page_writes) и даже если блоки данных повреждены (torn «разорваны», расщеплены), они смогут восстановиться.

Файлы журнала предзаписи

Наличие файлов журнала с момента начала контрольной точки которая инициируется в начале резервирования является критичным для восстановления. Каким образом организовано хранение файлов журнала?

В директорию PGDATA/pg_wal процессы экземпляра кластера производят запись в файлы журнала. Файлы экземпляром кластера не дублируются. Можно сказать что каждый WAL-файл в этой директории представлен в одном экземпляре (не экземпляре кластера, а экземпляре файла). В каждый момент времени есть текущий файл журнала, куда процессы экземпляра пишут (или последний файл куда писали, если экземпляр погашен). Размер этого файла всегда равен размеру других файлов (по умолчанию 16Мб) потому, что при создании следующего файла ему сразу задаётся размер. Размер задаётся либо (параметр wal_init_zero) командой записи последнего байта в файл размером wal_segment_size, либо командами записи пустых блоков вплоть до размера wal_segment_size. Это нужно, чтобы заранее было зарезервировано место в файловой системе и экземпляр не столкнулся с нехваткой места, а также для отказоустойчивости и быстроты: изменение размера файла - это операция с метаданными файловой системы. В зависимости от настроек монтирования файловая система может «журналировать только метаданные» (слово журналировать относится к файловым системам, в них тоже реализована логика защиты от пропадания питания), а при частом изменении размера файла (размер файла в файловой системе - это метаданные) в случае пропадания питания последние блоки файла либо будут потеряны, либо скорость записи в файл будет невысокой.

LSN: Log Sequence Number

В файлы журнала процессы экземпляра пишут записями переменной длины. Адрес каждой записи обозначается 64-битным числом «LSN» (Log Sequence Number), которое представляет собой порядковый номер байта журнала со времени создания кластера (момента когда начала производиться запись в журнал). Можно сказать, что LSN определяет «смещение от начала журнала» или «позицию в журнале предзаписи». Можно также сказать, что LSN - монотонно возрастающее целое число, которое указывает на запись в журнале.

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

Самый первый файл имеет название 000000010000000000000001. Название состоит из трёх частей по 8 знаков. Каждое число 32-битное, записывается в шестнадцатеричной форме. Максимальное число FFFFFFFF (32 единички в двоичной записи). Первое число это номер «линии времени» (Time LIne, TLI, ветвь времени, инкарнация). Это число увеличивается на единицу при открытии экземпляром кластера после процедуры восстановления для того, чтобы не допустить затирания файла журнала, так как восстановление не всегда попадает на 16-мегабайтную границу журнала, LSN на который восстановили кластер может указывать на байт в середине файла. В этом случае до восстановления в файле первая половина нужные записи, вторая - байты со значением ноль.

При достижении максимальных значений сброса в ноль (LSN wrap) LSN и линий времени не предусмотрено. Максимальное значение LSN довольно большое: 16777216 террабайт.

Физически запись в журнальные файлы производится 8-килобайтными блоками. На размер блока указывает параметр конфигурации wal_block_size, который задан при сборке СУБД Tantor и не меняется. Журнальные записи защищены контрольными суммами.

Размер файла журнала (WAL-сегмента), размер блока журнала, TimeLIneID хранятся в управляющем файле кластера (pg_control), поэтому зная LSN можно определить название файла в котором содержится запись переменной длины, на который указывает LSN.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/wal-internals.html 

Названия журнальных файлов и LSN

Рассмотрим подробнее LSN. Возможно вы задавались вопросом почему размер файлов журнала по умолчанию 16Мб?

В текстовом виде, который используется в файлах сообщений, опциях команд, функциях LSN представляют в виде двух 32-битных чисел, записанных в шестнадцатеричной форме (HEX), разделенных слэшем: XXXXXXXX/YYZZZZZZXXXXXXXX - «старшие» 32 бита LSN. Если размер файлов журнала 16Мб (значение по умолчанию), то YY - «старшие» 8 бит «младшего» 32-битного числа. ZZZZZZ - смещение в файле 16-мегабайтного журнала относительно его начала.

Максимальный размер файла журнала 1Гб, минимальный 1Мб и может принимать значения по степеням двойки (16, 32, 62, 128, 256, 512 1024Мб). Например, если установить размер файла журнала в 256Мб, то LSN будет выглядеть как XXXXXXXX/YZZZZZZZ. Если 1Мб (такой маленький размер не стоит использовать), то: XXXXXXXX/YYYZZZZZ. У других значений размера файла такого наглядного деления по разрядам нет. Размер файла журнала определяет максимальный размер журнального буфера в разделяемой памяти экземпляра, который устанавливается параметром wal_buffers. По умолчанию, при размере shared_bufers больше 512Мб, журнальный буфер выставляется в максимальное значение 16Мб.

Размер журнальных файлов можно задать при создании кластера утилитой initdb --wal-segsize=размер или после создания утилитой pg_resetwal --wal-segsize=размер.

Названия файлов журналов также зависят от размера файла. Для размера 16Мб формат следующий: 0000000NXXXXXXXX000000YY. Вторые 8 символов - старшие 32 бита LSN, потом 6 нулей, потом 2 символа старших 8 битов младшего 32-разрядного числа. Для размера 256Мб формат: 00000001XXXXXXXX00000YYY. первые 8 символов - номер перехода на новую линию времени.

Процесс восстановления

В процессе полного восстановления, информация о том, какая журнальная запись была сформирована самой последней перед падением экземпляра никуда не записывается. Процесс восстановления последовательно читает журнальные записи и если видит, что следующая запись в журнале содержит «мусор», то прекращает восстановление. При считывании следующей записи процесс восстановления в первую очередь ищет место, где должен быть размер журнальной записи. Если в этом месте нереальное значение, то прекращает восстановление, если реальное, то ищет место с контрольной суммой. Если контрольная сумма не совпадает, прекращает восстановление. Пример сообщения в файле сообщений экземпляра:

LOG:  invalid record length at CA/277E2A88: expected at least 26, got 0

процесс восстановления ожидал увидеть число не меньше 26 (минимальный размер журнальной записи), а увидел нули.

Процесс восстановления может сформировать название файла, так как знает номер линии времени, размер блока журнала, размер файла, LSN из управляющего файла. При изменении линии времени в директории PGDATA/pg_wal создаются текстовые файлы 0000000N.history с информацией о линиях времени. В журнале, формировавшемся на прежней линии времени данных о новой линии нет, так как экземпляр прежней линии времени, который формировал файл журнала, остановился.


Виды резервирования

Функции для работы с журналами

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

pg_switch_wal() переключает запись на новый WAL-файл, прежний не дописывается, хоть и имеет такой же размер, как и остальные файлы журналов.

pg_create_restore_point('текст') - создаёт в журнале запись LSN с текстовой меткой. Функция возвращает LSN начала этой журнальной записи. Метку можно указывать в параметре recovery_target_name чтобы указать что нужно накатить журналы до записи с меткой. Если создать несколько меток с одним и тем же названием, тогда восстановление остановится как только оно наткнется на запись с этой меткой.

pg_walfile_name('LSN') - выдает Название WAL-файла в котором должна встретиться запись с указанным LSN. Результат выдается расчётным способом на основе данных из управляющего файла.

pg_walfile_name_offset(LSN) - показывает не только расчётное имя файла, но и смещение в байтах относительно его начала.

pg_current_wal_lsn() - показывает LSN последнего байта («конца») последней журнальной записи, записанной в текущий файл журнала. До этого LSN включительно процессы в операционной системе должны видеть записанные, если будут читать файл журнала.

pg_current_wal_flush_lsn() - LSN последнего байта последней журнальной записи, которая считается надёжно сохранённой (fsync или другой способ вернул результат). Определяет LSN до которого включительно должны сохраниться журнальные записи после пропадания питания.

pg_current_wal_insert_lsn() - LSN последнего байта последней журнальной записи, которую сформировали процессы экземпляра в журнальном буфере и эта журнальная запись еще могла не попасть на диск. Используется процессами экземпляра для определения LSN своей записи, которую начнут формировать.

Утилитой командной строки pg_waldump имя_файла можно получить из WAL-файла в текстовом виде список LSN начала журнальных записей и их содержимое.

pg_lsn - тип данных. Для этого типа данных определено приведение типа 'литерал'::pg_lsn ,  оператор вычитания (или функция pg_wal_lsn_diff(LSN,LSN)), которым можно получить в байтах разницу между двумя LSN - объем журнальных данных.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/functions-admin.html#FUNCTIONS-ADMIN-BACKUP 

Холодное резервирование

Холодное резервирование - это резервирование на корректно остановленном кластере. В результате получается автономная копия кластера. Автономная или самодостаточная (self contained) это включающая в себя все файлы, чтобы мог запуститься экземпляр и дать доступ к данным.

Техника резервирования: определяется местоположение PGDATA, директории табличных пространств (символические ссылки в PGDATA/pg_tblspc), экземпляр корректно останавливается, проверяется что процессы экземпляра не остались в памяти и найденные директории копируются любыми утилитами.

Особенности подробно описаны в документации. Например, можно использовать снимки файловой системы, если она позволяет или предварительно выполнять копирование, а после остановки кластера обновлять файлы утилитой rsync в режиме подсчета контрольных сумм. Основное преимущество холодного резервирования - простота при этом теряется. Более практично резервирование работающего кластера, например, утилитой pg_basebackup.

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/backup-file.html 

full_page_writes

По умолчанию параметр full_page_writes включён. Это означает, что в журнал записывается всё содержимое (8Кб) каждого блока данных («страницы») при первом изменении этого блока (меняется в буфере кэша буферов) после каждой контрольной точки. Это большой объем данных. Зачем этот объем данных нужен? Размер блока 8Кб, а размер блока HDD, SDD, файловой системы не всегда 8Кб, а чаще 4Кб. В случае пропадания питания в блок данных, а они не дублируются, может быть записаны 4Кб, а другие 4Кб не запишутся и останутся от прежней версии блока. Такой блок называется расщепленный или «разорванный» (torn). Контрольная сумма в блоке не совпадёт и он будет считаться повреждённым. Блок может относиться к объекту системного каталога и экземпляр может не запуститься.

Почему при первом изменении страницы она записывается в журнал, а не при втором? Потому что восстановление начинается с LSN начала контрольной точки, которая завершилась до момента начала резервирования. Из журнала в буферный кэш читаются целые образы блоков (а не из файла данных) и к ним применяются изменения из журнала. Если кэш буферов небольшой, то блоки записываются на свои места в файлы данных по мере необходимости. Если бы блок записывался при втором изменении, то в процессе восстановления в журнале сначала шла запись об изменении блока и он бы читался из файла данных где он может быть поврежденным, запись журнала не смогла примениться и восстановление бы остановилось с ошибкой типа:

PANIC: WAL contains references to invalid pages

Процесс восстановления не знает о том, что дальше в журнале может встретиться образ страницы. При таких ошибках можно использовать ignore_invalid_pages=on (только если full_page_writes был включён) надеясь на то, что целый образ страницы встретится позже. Если full_page_writes=off, то использовать ignore_invalid_pages не стоит.

Наличие full page writes позволяет не зависеть от того сбросит ли операционная система измененные страницы файлов данных на диск из своего кэша, а это кэш на запись или от порядка сброса блоков. Операционная система может работать с 4Кб блоками в своем кэше и записывать их в произвольном порядке. Если хоть где-то на пути от процесса экземпляра до сектора диска (или контроллера плашки SSD) используется блок не 8Кб, а меньше, то вероятность получить большое число разорванных блоков при пропадании питания или сбое операционной системы высока и отключать параметр не стоит.

При резервировании реплики full_page_writes должен быть включён на мастере.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-wal.html#GUC-FULL-PAGE-WRITES   

Утилита pg_basebackup

Создаёт резервную копию всего кластера на работающем экземпляре. Не останавливает обслуживание, не блокирует работу пользовательских сессий.

Создаёт копию всего кластера. Не может создавать копию отдельных баз данных или объектов.

Утилита подсоединяется к экземпляру через сетевое соединение или Unix-сокет. По умолчанию создаёт два соединения по протоколу репликации, в котором нет обычных команд SQL, но есть команды для получения файлов из файловой системы сервера. Через первое соединение создаётся бэкап, через второе параллельно начинают передаваться журнальные файлы.

Для подсоединения к экземпляру по протоколу репликации можно дать отдельные разрешения ролям кластера. Утилита входит в стандартную поставку.

Утилита по умолчанию создаёт резервную копию на том хосте, на котором запущена. Запускаться может на хосте, отличном от хоста где работает экземпляр. Кластер будет резервироваться через сетевое соединение.

На время резервирования включает full_page_writes, если параметр был отключен.

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

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

Может выполнять резервирование подсоединившись к экземпляру, обсуживающую физическую реплику (копию) кластера, не нагружая экземпляр основного (primary, мастера) кластера. Это называют «backup offloading».

Инкрементальное резервирование отсутствует, создаётся копия всего кластера.

Для наблюдения за процессом резервирования есть представление pg_stat_progress_basebackup.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/app-pgbasebackup.html 

Утилита pg_verifybackup

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

По умолчанию pg_basebackup создает файл манифеста (manifest_file). Это текстовый файл в формате json с контрольными суммами для каждого зарезервированного файла по алгоритму CRC32C. Содержимое самого манифеста защищено контрольной суммой по алгоритму SHA256. Менять алгоритмы не нужно.

Стоит ли отключать создание файла манифеста при резервировании? Не стоит. Если не менять алгоритмы, то лишней нагрузки нет.

Если файл манифеста есть и не удалялся, то утилитой pg_verifybackup можно проверить, что файлы соответствуют манифесту, то есть не повредились в процессе хранения. Утилита выдаёт отчет по исчезнувшим, изменённым и добавленным файлам. Также утилита проверяет самодостаточность (автономность) бэкапа - можно ли по журнальным файлам (если не отказывались от их резервирования) синхронизировать резервную копию на момент завершения бэкапа. Проверка выполняется с помощью утилиты pg_waldump проверяя наличие в зарезервированных файлах журнала нужных LSN-записей. Список нужных записей был передан экземпляром утилите pg_basebackup во время резервирования и помещен в файл манифеста.

Утилита не проверяет файлы postgresql.auto.conf, standby.signal, recovery.signal и их наличие.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/app-pgverifybackup.html 


Журнал предзаписи

Архив журналов

Резервная копия может быть автономной. Чтобы можно было восстановиться с неё на последний момент времени, нужно будет накатить на эту копию журнальные файлы со времени создания копии до последнего момента. По умолчанию кластер сохраняет в директории PGDATA/pg_wal файлы журналов для целей восстановления согласованности файлов кластера после аварийной остановки экземпляра, то есть с начала последней контрольной точки. Журнальные файлы могут удерживаться параметрами конфигурации долгое время, но директория PGDATA/pg_wal может быть не лучшим местом для хранения журналов, если это дорогостоящее устройство хранения, а также в целях защиты от удаления злоумышленниками. Бэкапы и журналы по возможности должны храниться на хосте к которому нет доступа резервируемого хоста, чтобы злоумышленник не смог стереть бэкапы.

Способы организации архива журналов:

  1. Установив параметр archive_command='команда' и archive_mode=on. У этого метода есть недостаток - текущий файл журнала (в который пишут процессы экземпляра) начнет копироваться только когда он перестанет быть текущим. Если текущий файл потеряется, то данные в нем будет неоткуда взять и будут потеряны транзакции. Это обычно неприемлемо.
  2. Утилитой pg_receivewal. Эта утилита может принимать журнальные данные без задержки. Недостатком является то, что нужно автоматизировать запуск утилиты и перезапускать в случае сбоя.
  3. Использовать сторонние расширения, автоматизирующие резервирование.
  4. Использовать физические реплики.

Отсутствие потерь (Durability)

Журналы можно забирать из «архива», но важным для полного восстановления является накат записей из самого последнего файла журнала, которые могли не успеть передаться в архив. Потеря даже одной зафиксированной транзакции обычно неприемлема (свойство Durability из свойств ACID транзакции). Архивы журналов не гарантируют что они содержат все транзакции, а последний журнал на диске поврежденного кластера может не сохраниться например в результате катаклизма (disaster: пожар, затопление, разрушение здания где находятся системы хранения файлов). Файл журнала в директории PGDATA/pg_wal не должен являться «точкой сбоя». Использование pg_receivewal и/или физической реплики с подтверждением ими фиксации транзакции обеспечит отсутствие потерь транзакций в случае полной  потери хоста кластера со всеми дисковыми системами (disaster).

Подтверждение фиксации транзакций настраивается параметрами synchronous_commit и synchronous_standby_names.

Монтирование pg_wal на системах хранения с дублированием может защитить от сбоя диска, но не защитит от злоумышленника который может стереть файл журнала. В последнем случае можно задаться вопросом: нужно ли вести архивы или удерживать файлы в pg_wal? Технически архивы вести удобнее, чем настраивать удержание файлов в pg_wal. Также копирование в архивы освобождает место на дорогостоящем высокоскоростном устройстве, где располагают pg_wal. Также стоит принять во внимание, что в целях безопасности нужно, чтобы хост кластера не имел доступа к бэкапам и архивам журналов. Если злоумышленник получит доступ к хосту кластера, то первым делом злоумышленники удаляют все бэкапы. Хосты где хранятся бэкапы стоит физически отключать от сети (на уровне железа, сетевых портов) после выполнения резервирования чтобы в случае полного доступа к программным системам злоумышленник не смог стереть бэкапы и можно было бы восстановиться.

Утилита pg_receivewal

Утилита pg_receivewal подсоединяется по протоколу репликации и принимает поток журнальных записей по мере того как они формируются на экземпляре и сохраняет принятые записи в файлы. Названия файлов и размеры такие же как те, которые формируются экземпляром. Текущий файл, чтобы не было путаницы утилита называет как имя.partial

pg_receivewal по умолчанию накапливает журнальные данные в памяти, а сохраняет в файл при закрытии файла. Если нужно чтобы утилита записывала принятые данные без задержки, утилиту нужно запустить с параметром --synchronous. Этот же режим должен использоваться если утилита будет подтверждать транзакции в режиме синхронной фиксации, установленной параметром synchronous_commit. Этот параметр определяет после завершения какого уровня обработки журнальной записи процесс будет выдавать клиенту сообщение об успешной фиксации COMMIT COMPLETE.

Значения:

remote_apply к pg_receivewal неприменимо, только физические реплики могут подтвердить транзакцию. Не стоит ставить, так как скорость фиксации транзакций резко падает.

on - значение по умолчанию. Транзакция подтверждается после того как pg_receivewal или реплика получит ответ от своей операционной системы, что она записала журанльные страницы на диск (выполнила fsync).

remote_write - процесс pg_recievewal или wal receiver реплики послал команду своей операционной системе записать журнальные блоки на диск. Операционная система может задержать их в своём кэше файловой системы и если пропадет питание, то блоки могут быть потеряны. Это значение разумный выбор, еcли вероятность сбоя основного хоста и следом за ним резервного мала, а значение on приводит к деградации производительности, которую нельзя устранить другими способами (например, параметром commit_siblings или заменой fsync на стороне pg_recievewal).

local - транзакция подтверждается после записи в локальный файл журнала и fsync (метод используемый по умолчанию).

off - не стоит ставить на уровне кластера. Может ставиться разработчиками приложений на уровне сессий или транзакций.

Если synchronous_standby_names не задано, то это эквивалентно local и текущий журнал - единственная точка сбоя.

Утилита может сжимать сохраняемые журналы.

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/app-pgreceivewal.html 

Слот репликации

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

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

Клиенты (pg_receivewal, pg_basebackup, процессы wal receiver, logical replication worker экземпляров), подключающиеся по протоколу репликации, могут указывать имя слота репликации. Наличие слотов удерживает файлы журналов, которые не были получены с использованием этих слотов.

Слоты создаются и удаляются командами репликационного протокола, а также функциями и командами SQL. Физические слоты репликации создаются на кластере-мастере и относятся к нему. Каждая реплика использует свой слот. Временный слот существует только на время одной репликационной сессии и удерживает журналы только на время сессии.

Если при создании слота LSN не указан, то он устанавливается при первом подсоединении клиента. Если клиент не принимает журнальные данные (остановился), то файлы журналов будут удерживаться и заполнят всё свободное место в директории PGDATA/pg_wal. Чтобы этого не произошло стоит установить ограничение параметром max_slot_wal_keep_size.

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

Для создания физического или временного физического слота можно использовать функцию pg_create_physical_replication_slot('имя').

Для удаления слота pg_drop_replication_slot ('имя').

https://docs.tantorlabs.ru/tdb/ru/15_6/se/functions-admin.html#FUNCTIONS-REPLICATION 


Резервирование

Создание базовой резервной копии

Утилита pg_basebackup может создавать бэкапы в форматах plain и tar. Второй формат не рассматриваем, всё написанное ниже относится к формату plain.

Для создания бэкапа достаточно задать директорию параметром -D директория или --pgdata=директория. Если директория не существует, утилита её создаст и все директории в её пути, если они отсутствуют. Если директория существует, то она должна быть пустой, это защищает от перезаписи файлов, которые могут быть важны. По умолчанию директория создаётся на том хосте, где запущена утилита.

Если в кластере были созданы табличные пространства (PGDATA/pg_tblspc содержит символические ссылки), то будут созданы директории на которые указывают символические ссылки. То есть структура каталогов табличных пространств будет одинакова на кластере и хосте, где создаётся бэкап. Если бэкап создается на том же самом хосте, то нужно будет указать «мэппинг» - перечислить директории табличных пространств и куда их резервировать параметром:

-T откуда=куда или --tablespace-mapping=откуда=куда.

Все директории указывать по их абсолютным путям, а не относительным. Можно перечислить лишние директории, ошибки не будет. Если же какую-то директорию не указать, то будет выдана ошибка, что директория не пустая. Символические ссылки, находящиеся внутри поддиректории pg_tblspc директории c бэкапом будут указывать на новые директории.

Полезный параметр -P или --progress покажет в какой фазе резервирования находится утилита.

Параметр -r скорость или --max-rate=скорость позволяет ограничить скорость резервирования данных, чтобы снизить нагрузку на ввод-вывод. Диапазон от 32 КБ/с до 1024 МБ/с. На скорость передачи журнальных данных влияет, только если выбран метод передачи журналов fetch, который не имеет смысла использовать.

В начале резервирования мастера (основной кластер, не физическая реплика) утилита инициирует контрольную точку. По умолчанию контрольная точка выполняется в соответствии со значением параметра checkpoint_completion_target, чтобы не нагружать ввод-вывод, то есть ее длительность можно оценить как checkpoint_timeout*checkpoint_completion_target. Если хочется выполнить контрольную точку максимально быстро, можно использовать параметр -c fast или --checkpoint=fast.

Параметром -t или --target можно (но не нужно) резервировать в директорию на хосте кластера, а также резервировать «в никуда» (--target=blackhole). Последний режим может использоваться для измерения производительности: какая часть времени резервирования тратится на чтение файлов.

Утилита резервирует директории и файлы, которые ей неизвестны. Поэтому не стоит хранить в PGDATA файлы, которые вы бы не хотели видеть в бэкапе, например файлы сообщений большого размера.

Утилита создаёт файлы backup_manifest, backup_label. Файл backup_label содержит те же данные, что и в файле pg_control бэкапа.

Утилита не резервирует файлы, которые известно что не нужно резервировать. Такие файлы описаны в документации:

https://docs.tantorlabs.ru/tdb/ru/15_6/se/continuous-archiving.html#BACKUP-LOWLEVEL-BASE-BACKUP-DATA 

WAL-G

WAL-G дополнительно поставляемое с СУБД Tantor клиентское приложение.

Используется для резервирования кластера и файлов журналов по протоколу S3, который используют и облачные хранилища файлов. Для резервирования во внутренней сети доступно программное обеспечение, например, minio.

Одно из преимуществ утилиты - возможность инкрементального (второе название - дифференциального) резервирования. В WAL-G это называется «дельта-копии». Они хранят страницы файлов, изменившиеся с предыдущего бэкапа.

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

Не поддерживается поточная передача журнальных записей, журналы передаются по файлам (WAL-сегментам).

Если хранилище поддерживает протокол S3 и не поддерживает монтирование по сети (обычно, NFS), то WAL-G может быть полезен.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/wal-g.html 


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

Обзор 

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

Резервирование на логическом уровне в постгрес - это формирование текстового файла или файлов, позволяющих воссоздать объекты их данные, не отличающихся с точки зрения логики приложения от образа резервируемых объектов. Данные и объекты после восстановления находятся в том состоянии, в котором они были на момент начала выгрузки. В файле содержатся команды SQL или текст, на основе которого можно сгенерировать команды SQL.

Инструменты логического резервирования:

Инструменты восстановления с логической копии:

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

Примеры использования

Логическое резервирование позволяет скопировать данные и/или объекты в другую базу данных на том же или другом кластере той же или другой версии и производителя. Зачем это может потребоваться?

  1. Для перехода на новую основную версию СУБД Tantor. Если время выгрузки и загрузки приемлемо, это оптимальный способ.
  2. Смена параметров кластера или базы данных, которые не меняются без пересоздания кластера или базы данных.
  3. Для гарантированной проверки того, что данные не повреждены. Только выгрузка на логическом уровне может это гарантировать.
  4. Для простой выгрузки содержимого отдельной базы данных. Физическое резервирование с помощью pg_basebackup не позволяет выгружать отдельно базы данных. В pg_probackup эта опция экспериментальная.
  5. Перенести данные в другие системы хранения, например, СУБД других производителей или загрузить данные из сторонних источников.
  6. Получить текстовый командный файл (скрипт) для установки приложения.
  7. Быстро и просто зарезервировать объекты и данные на любых уровнях (кластер, базы, объекты баз, глобальные объекты), получив целостную копию (на один момент времени).

Сравнение логического и физического резервирования

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

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

Одно из преимуществ логического резервирования постгрес в том, что формат создаваемых файлов («дамп») текстовый со стандартными командами SQL, а не закрытый бинарный формат.

Команда COPY

Особенности выгрузки:

  1. Можно выгрузить указав имя таблицы (но не представления) или любую команду SQL, возвращающая данные: WITH, SELECT (любой сложности), команда VALUES, команды с выражением RETURNING (INSERT, UPDATE, DELETE). Команду нужно заключать в круглые скобки, имя таблицы не нужно.
  2. Обычно используется имя таблицы если нужно выгрузить все строки, либо SELECT с фразой WHERE, если нужно выгрузить часть строк. Команда VALUES мало распространена, но это стандартная команда SQL.
  3. Вместо имени таблицы указывать имя представления нельзя, но имя представления можно использовать в команде SQL.
  4. Есть десять параметров, которыми можно настроить формат и особенности выгрузки: кодировку, символы квотирования, экранирования, как обрабатывать NULL (пустые значения), нужно ли заключать текст в кавычки, нужно ли в первую строку выводить названия столбцов:

COPY таблица [( столбцы )]  

 | (SELECT|VALUES|.RETURNING)

TO 'файл'|PROGRAM 'команда'

 | STDOUT

WITH (

FORMAT text | csv | binary

DELIMITER 'символ'

NULL 'маркер'

HEADER true | false

QUOTE 'символ'

ESCAPE 'символ'

FORCE_QUOTE (столбцы)|*

FORCE_NOT_NULL (столбцы)

FORCE_NULL (столбцы)

ENCODING 'имя_кодировки);

Синим цветом помечены опции, которые можно указывать только при выгрузке, а не загрузке в таблицу. Поддерживается две вариации синтаксиса команды COPY (для совместимости с PostgreSQL 9 и 7 версий). Вариации синтаксиса отличаются порядком следования ключевых слов. Это нужно знать, так как в книгах можно встретить примеры с таким синтаксисом. Формат binary может обрабатываться быстрее, чем текстовый и CSV форматы, но он менее переносим и выгрузить-загрузить можно только в тот же тип данных, а не в пределах семейства типов. Команда COPY не входит в стандарт SQL и специфична для PostgreSQL.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-copy.html 

Команда COPY .. FROM

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

COPY таблица [( столбцы )]
FROM 'файл'|PROGRAM 'команда'
 | STDIN
WITH
(
 FORMAT text | csv | binary
 FREEZE true | false
DELIMITER 'символ'
NULL 'маркер'
DEFAULT 'выражение'
HEADER true |
MATCH
 QUOTE 'символ'
ESCAPE 'символ'
ENCODING 'имя_кодировки
)
 [WHERE выражение];

Синим цветом помечены опции, которые можно указывать только при загрузке в таблицу, а не при выгрузке.

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

HEADER MATCH используется для проверки того, что названия столбцов и их порядок в первой строке загружаемых данных и в таблице совпадают. Может использоваться как дополнительная проверка того, что столбцы не перепутаны при выгрузке-загрузке.

Можно задать опциональное выражение WHERE. В этом выражении нельзя использовать подзапросы. При вычислении выражений не видны изменения, которые вносит сама команда COPY. На последнее нужно обращать внимание только если в выражении WHERE вызываются функции с уровнем изменчивости VOLATILE и ожидается, что они будут видеть изменения, а они не видят.

DEFAULT задаёт литерал. Если он встретится во входных данных, то будет вставлено значение по умолчанию, установленное в определении таблицы. Аналог: insert into .. values (.., DEFAULT, ...)

Пока команда COPY ( и TO и FROM) работает, можно отслеживать её работу через представление pg_stat_progress_copy.

В psql имеется команда \copy. Синтаксис \copy похож на COPY, но действия выполняет утилита psql. Отличие от COPY в том, что с файлом работает psql на том хосте где запущен psql, а не серверный процесс. Поскольку stdin и stdout при подсоединении по сети направляются на клиента, команда COPY может работать с файлами на клиенте с помощью перенаправления ввода-вывода.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-copy.html 

Команда \COPY

\copy это команда psql. Синтаксис \copy похож на синтаксис команды COPY, но действия выполняет утилита psql. Отличия от COPY:

  1. \copy набирается на одной строке, COPY можно набирать на нескольких строках
  2. \copy .. from в формате CSV ошибочно обрабатывает единственное в строке значение \. как конец ввода и следующие строки не загружает
  3. в COPY можно использовать переменные подстановки, раскрытие обратных кавычек (символ `).  Для \copy конец строки всегда воспринимается как аргументы \copy, и в этих аргументах не выполняется ни подстановка переменных, ни раскрытие обратных кавычек
  4. количество обработанных строк \copy .. to stdout не отображает 
  5. при выполнении \copy ... to stdout вывод направляется в то же место, что и вывод psql команд. Для чтения/записи стандартного ввода/вывода psql, вне зависимости от источника текущей команды или параметра \o, можно использовать from pstdin или to pstdout
  6. утилита psql работает с файлом на том хосте, где запущен psql. Это медленнее, чем работа серверного процесса с файлом. Для больших объёмов данных COPY эффективнее.

Поскольку stdin и stdout при подсоединении по сети направляются на клиента, команда COPY может работать с файлами на клиенте с помощью перенаправления ввода-вывода.

Вместо \copy .. to можно использовать COPY ... TO STDOUT и завершить её командой \g имя или \g | программа.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/app-psql.html#APP-PSQL-META-COMMANDS-COPY 


Утилиты логического резервирования

Утилита pg_dump

pg_dump - утилита создания логической резервной копии содержимого базы данных. Утилита подсоединяется к одной базе данных так же как psql, использует обычные команды SQL, устанавливает блокировки самого низкого уровня ACCESS SHARE, такие же как команда SELECT. Эта блокировка нужна, чтобы во время выгрузки выгружаемые объекты не были удалены. Единственная блокировка, несовместимая с ACCESS SHARE это ACCESS EXCLUSIVE. Утилита выгружает данные согласованно, то есть на один момент времени. Утилита может выгружать данные параллельно несколькими процессами, согласованность на один момент времени при этом сохраняется. Для этого используется стандартный функционал - экспорт моментального снимка. Для выгрузки по умолчанию использует высокоэффективную команду COPY, но может формировать и набор команд INSERT. Может выгружать определения объектов без данных и наоборот. Имеет гибкие настройки, позволяющие детально выбирать какие типы объектов выгружать.

Выгружает данные в одном из четырёх форматов:

  1.  plain - по умолчанию. Формируется скрипт с набором команд SQL. Для загрузки используется утилита psql. Основной недостаток - нельзя указать несколько процессов для одновременной выгрузки
  2.  custom - выгружает в архивном формате, по умолчанию сжатом. Для восстановления используется утилита pg_restore, которая может читать формируемые файлы. Выгружать в несколько потоков нельзя, восстанавливать можно. Может использоваться с пайпом:
    pg_dump -F custom параметры | pg_restore параметры
  3.  directory - создаёт каталог, в котором для каждой таблицы и lob будут созданы отдельные файлы и файл оглавления. Для восстановления используется утилита pg_restore. Можно указывать количество потоков, которые одновременно будут выгружать данные - это основное преимущество по сравнению с форматом custom. Восстановление также можно проводить в несколько потоков.
  4.  tar - похож на directory, только не распараллеливается и не сжимается. Для восстановления используется pg_restore. Преимуществ по сравнению с форматом directory не имеет.

pg_dump на низком уровне выполняет команды SELECT.

Использование пайпа (pipe, «канал») позволяет направлять stdout на stdin утилиты psql и перегружать данные не создавая файл, что может сэкономить место в файловой системе.

По умолчанию для форматов custom и directory используется сжатие. Сжатие может существенно (в десятки раз) замедлять выгрузку. Можно использовать более быстрый алгоритм -Z zstd или отключить сжатие параметром -Z 0

https://docs.tantorlabs.ru/tdb/ru/15_6/se/app-pgdump.html 

Параллельная выгрузка

Время выгрузки почти линейно зависит от объема выгружаемых данных. Поскольку в процессе выгрузки данные обрабатываются на логическом уровне, то узким местом может стать ядро центрального процессора, которое будет обслуживать pg_dump. Для уменьшения времени выгрузки может использоваться выгрузка в несколько потоков. Выгрузку будут выполнять серверный процесс и рабочие процессы. Одну таблицу может выгружать один рабочий процесс. Выгружать в параллельном режиме можно только в формате directory. Другие три формата выгружают в один поток. Количество потоков нужно задать параметром -j N или --jobs=N. При выгрузке создастся N+1 сессий с базой данных. Серверный процесс, обслуживающий pg_dump создаст моментальный снимок и экспортирует его. Рабочие процессы будут использовать этот моментальный снимок, чтобы выгрузка выполнилась на один момент времени (была согласованной).

В параллельном режиме, в начале работы, серверный процесс запрашивает блокировки уровня ACCESS SHARE на все объекты, которые будут выгружаться рабочими процессами. Это делается для того, чтобы нельзя было удалить объекты пока работает выгрузка. Количество таких блокировок ограничено значением max_locks_per_transaction * (max_connections + max_prepared_transactions). Если число выгружаемых объектов (таблиц) превышает это число, то серверный процесс выдаст ошибку о превышении количества блокировок и завершится не начав выгрузку. В этом случае можно посчитать количество запланированных к выгрузке таблиц и увеличить max_locks_per_transaction на основном кластере. На всех репликах значения вышеуказанных параметров должны быть не меньше, чем на мастере.

С режимом ACCESS SHARE несовместимы только команды, устанавливающие блокировку самого высокого уровня - ACCESS EXCLUSIVE (монопольный, эксклюзивный доступ). Это команды VACUUM FULL, DROP, ALTER, TRUNCATE, LOCK IN ACCESS EXCLUSIVE MODE, REFRESH MATERIALIZED VIEW, а также команды, которые могут устанавливать эту блокировку на короткое время в конце своей работы. Если какая-то сессия запросит блокировку на объект в режиме в монопольном режиме, то запрос на блокировку будет поставлен в очередь и не де даст другим сессиям получить блокировку на объект до истечения значения параметра lock_timeout, если он был установлен. Любая попытка доступа к этому объекту будет вставать в очередь, вслед за эксклюзивной блокировкой. Так как рабочие процессы используют собственные сессии, то перед выгрузкой данных из объекта они запрашивают блокировку ACCESS SHARE и встают в очереди вслед за ACCESS EXCLUSIVE. Чтобы не допустить бесконечного ожидания, рабочие процессы запрашивают блокировку в режиме NOWAIT. Если рабочий процесс не сможет получить блокировку, то вся выгрузка прекратится.

Утилита pg_restore

pg_restore восстанавливает базу данных или объекты из резервной копии, созданной утилитой pg_dump во всех режимах, кроме text. В режиме text создается файл, который выполняется утилитой psql, а не pg_restore.

Работает в трёх режимах:

  1. если указан параметр -d имя или --dbname=имя, где значение параметра это имя базы данных или строка соединения, то pg_restore подключается к этой базе данных и восстанавливает содержимое архива в неё. Если указать ключ, а значение не указывать, то будет использоваться переменная окружения PGDATABASE. Если и переменная не задана, то в качестве имени базы будет взято имя пользователя операционной системы.  В этом режиме возможна загрузка в несколько сессий для входных файлов дампа в формате custom или directory. Формат tar не поддерживает параллельную загрузку. Параллельные процессы выполняют наиболее длительные действия, такие как загрузка данных в таблицы и создание индексов
  2. если указан параметр -l или --list, то выводится список объектов архива (TOC, table of contents, оглавление). Файл списка можно отредактировать, чтобы не загружать часть объектов. Отредактированный файл списка передаётся параметром -L файл или --use-list=файл
  3. если параметры -d и -l не указаны, но указан -f, то создаётся скрипт с командами SQL. Формируемый pg_restore скрипт будет соответствовать выводу pg_dump в формате plain.

Скрипт генерируется одним процессом.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/app-pgrestore.html 

Обзор возможностей pg_restore

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

  1.  Параметром -s или --schema-only можно восстановить только определения объектов, не загружая данные. Позже можно загрузить сами данные, указав параметр --data-only. Загрузятся строки таблиц, lob, и установятся значения последовательностей. Имеет смысл использовать --disable-triggers для предварительного отключения триггеров перед загрузкой строк в таблицы.
  2.  Параметры --clean --if-exists перед созданием объекта генерируется команда DROP IF EXISTS. Без второго параметра выдаются информационные сообщения в stderr (обычно это не требуется).
  3.  --create создать базу данных. В параметре подсоединения -d нужно будет указать любую существующую базу для выдачи команды создания базы данных и подсоединения к ней.
  4.  --exit-on-error завершить работу, если возникнет ошибка. По умолчанию утилита продолжает работать и в конце работы выдаёт число ошибок.
  5.  -I имя. Сгенерировать команду создания указанных индексов. Можно указывать параметр несколько раз, если нужно создать несколько индексов.
  6.  Для загрузки содержимого не всех, а только части схем можно использовать параметры -n или -N
  7.  --no-owner не восстанавливать права владения. Используется, если набор ролей в кластере отличается от тех, что были в исходном кластере
  8.  -P восстанавливать только указанные подпрограммы (процедуры и функции).
  9.  -t восстановить только перечисленные «relations» (таблицы, представления, материализованные представления, последовательности, внешние таблицы)
  10.  -T восстановить только указанные триггера
  11.  -x или --no-privileges или --no-acl не генерировать команды GRANT, REVOKE
  12.  --section восстановить секции таблиц
  13.  Параметром --no-tablespaces можно очищать команды CREATE от названий табличных пространств. Объекты будут загружаться в табличное пространство по умолчанию. Используется, если в кластере нет табличных пространств, которые были в исходном кластере.

Утилита pg_dumpall

Создаёт скрипт, позволяющий восстановить образ кластера, то есть все объекты кластера во всех базах данных и общие объекты. Скрипт содержит команды SQL, его можно выполнить в psql и восстановить все базы данных и их содержимое.

Утилита выгружает общие объекты кластера (роли, табличные пространства и права, выданные для параметров конфигурации) и последовательно запускает pg_dump для каждой базы данных в кластере в режиме plain. Для подсоединения требуется подключаться к экземпляру несколько раз к каждой из баз данных. Если используется аутентификация по паролю, то может потребоваться вводить его несколько раз, поэтому удобно использовать аутентификацию, не требующую вводить пароль.

В скрипте нет команды создания кластера. При запуске сгенерированного скрипта, psql должен подсоединиться к экземпляру кластера, который можно создать утилитой initdb. Также нужно, чтобы директории табличных пространств находились по тем же путям, по которым они находились в исходном кластере. Создавать сами табличные пространства не обязательно - команды создания табличных пространств будут присутствовать в скрипте.

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

Использование пайпа (pipe, «канал») позволяет направлять stdout на stdin утилиты psql и перегружать данные не создавая файл, что может сэкономить место в файловой системе.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/app-pg-dumpall.html 

Функционал pg_dumpall

Утилита имеет много параметров, но большая часть из них относится к утилите pg_dump, которую будет запускать pg_dumpall.

Параметр -g или --globals-only позволяет выгрузить общие объекты кластера: роли и определения табличных пространств. Используется когда нужно ускорить копирование содержимого кластера: сначала перегружаются роли и табличные пространства, а потом параллельно для каждой базы запускается выгрузка в желаемом режиме. Например, в параллельном: pg_dump --format=directory --jobs=N.

--clean создаёт команды DROP для баз данных, ролей, табличных пространств. Полезен даже с пустым кластером, так как встроенные базы данных postgres и template1 будут пересозданы и получат свойства, которые эти базы имели в исходном кластере (параметры локализации). С этим ключём обычно используют --if-exists.

-r или --roles-only выгружать только роли, без баз данных и табличных пространств

-t или --tablespaces-only выгружать только табличные пространства, без баз данных и ролей.

--exclude-database=шаблон не выгружать базы данных с именами соответствующими шаблону.

--no-tablespaces не добавлять в команды имена табличных пространств. С этим параметром все объекты будут созданы в табличном пространстве по умолчанию.

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

Параметр --binary-upgrade предназначен для использования утилитой pg_upgrade (совместно с --globals-only или --schema-only), он позволяет сохранить названия файлов данных для объектов. Использование для иных целей не рекомендуется и не поддерживается.

Строки большого размера

Первая проблема:

Типы данных text и bytea могут хранить поля размером до 1Гб. В процессе выгрузки (COPY) или обработки данных любыми командами выделяется буфер, размер которого не может превышать 1Гб. По умолчанию команда COPY выводит значения полей в текстовом формате. В этом формате для символов типа перехода на новую строку, табуляции, забоя используются спецпоследовательности типа \r \t \b которые занимают два байта. В этом формате поле, содержащее спецсимволы может превысить 1Гб. При выгрузке поля bytea в текстовом виде, его размер также увеличивается и будет выдана ошибка:

ERROR:  out of memory

DETAIL:  Cannot enlarge string buffer containing 1073741822 bytes by 1 more bytes.

Вы этом случае можно использовать бинарный формат: COPY .. TO .. WITH BINARY;

Вторая проблема:

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

ERROR:  out of memory

DETAIL:  Cannot enlarge string buffer containing 536870913 bytes by 536870912 more bytes.

При выгрузке любых типов данных, в том числе из lob размер строки не может превышать 1Гб. Такие поля придётся выгружать по частям: по столбцам; фильтруя строки и выгружая проблемные строки отдельно по полям.

Параметр утилиты pg_dump -B или --no-large-objects позволяет не выгружать lob. Для работы с lob имеются функции lo_import() и lo_export().

Комментарий:

При работе со строками большого размера серверные процессы могут пытаться выделять память больше 1Гб. Например, текущий размер строкового буфера 999Мб, идет попытка увеличить для обработки ещё ещё одного поля размером 1Гб, в операционную систему уходит запрос на выделение ещё 1Гб. Если физической памяти под этот 1Гб нет, то этот серверный процесс (или любой процесс) получает сигнал 9 (SIGKILL) от oom-kill. Если физической памяти достаточно, то серверный процесс выдает клиенту "ERROR: out of memory" и продолжает работать.


Раздел 8. Репликация

Физическая репликация

Обзор

Физическая репликация

До сих пор мы рассматривали работу с одним кластером, обслуживаемым одним экземпляром на одном хосте. Один хост может выйти из строя, как и центр обработки данных, в котором находится хост. Для высокой доступности (High Availability, HA) содержимого баз данных нужно использовать по крайней мере ещё один хост со своей системой хранения файлов и сделать так, чтобы при отказе первого хоста второй хост имел те же самые данные, что и первый и смог обслуживать приложения-клиенты.

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

Модель использования: имеется кластер с которым работают клиентские приложения. Его называют основной (primary) или мастер (master, ведущий) кластер. Основной кластер только один в конфигурации, использующей физическую репликацию. Делается физическая резервная копия файлов этого кластера на резервный хост. Эта копия называется резервным (standby) кластером или физической репликой или просто «реплика». Настраивается передача журнальных данных на хост резервного кластера. Запускается экземпляр на резервном хосте. Экземпляр принимает и накладывает на файлы резервного кластера изменения. Таких резервных кластеров может быть несколько, они могут располагаться на разных хостах.

Резервный кластер обычно открывается в режиме для чтения данных (горячий резерв, hot standby) и может обслуживать запросы. При этом резервный кластер продолжает накладывать изменения на свои файлы и они становятся видны сессиям, подключённым к экземпляру, обслуживающему резервный кластер. На резервный кластер можно перенести  долгие, аналитические запросы, которые обычно формируют отчёты.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/high-availability.html


Мастер и реплика

Мастер и реплики должны использовать ту же основную версию СУБД Tantor. Кластер реплицируется целиком - со всеми базами данных. Исключить из репликации часть объектов нельзя. Директории табличных пространств могут отличаться, так как на директорию табличного пространства указывает только символическая ссылка в директории PGDATA/pg_tblspc.

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

Реплики могут передавать журнальные записи мастера по протоколу репликации другим клиентам например, другим репликам. Это называется каскадирование (cascading replication). Реплики, получающие журнальные записи не от мастера не могут подтверждать транзакции в синхронном режиме, их нельзя указывать в параметре synchronous_standby_names.

Реплики и архив журнала

Передавать на реплики журнальные записи можно всеми доступными способами. Например, реплика может забирать журнальные файлы из произвольной директории, например, директории куда складывает полученные файлы утилита pg_receivewal или любая другая (например, указанная в параметре archive_command). Большие возможности даёт получение журнальных записей по протоколу репликации с использованием слота репликации, так же как и утилита pg_receivewal. Только вместо pg_receivewal используется фоновый процесс экземпляра реплики, называющийся walreceiver.

Реплика может быть настроена на использование как слота репликации, так и файлов журналов (параметр restore_command на реплике). Если реплика не сможет по любым причинам получить журнальную запись по протоколу репликации, она выполнит команду, указанную в restore_command и если команда успешно выполнится попробует прочесть файл журнала. При этом реплика будет пытаться восстановить соединение по протоколу репликации и если сможет получать журнальные записи по протоколу репликации, то будет это делать.

Примечание: архив журнала рассматривался в главе «Физическое резервирование».

Настройка основного кластера

Основной кластер (мастер) уже скорее всего используется и успешно обслуживает клиентские приложения. Создать и настроить реплику можно без простоя обслуживания клиентов мастером. Реплика подсоединяется по протоколу репликации, нужно настроить параметры аутентификации для роли под которой будет подсоединяться реплика. Может потребоваться поменять значения параметров конфигурации кластера, которые не меняются без рестарта экземпляра, Параметры:

wal_level (по умолчанию replica) - должно быть значение replica или logical. При изменении значения требуется перезапуск экземпляра

max_walsenders (по умолчанию 10) Одна реплика использует одно соединение к walsender, но при сетевом сбое может переподсоединиться, при этом предыдущее соединение может существовать до walsender_timeout. pg_basebackup может использовать два соединения. При изменении значения требуется перечитывание параметров конфиурации.

max_replication_slots (по умолчанию 10) - должно быть не меньше числа существующих слотов, иначе экземпляр не запустится. Каждая реплика (независимо от каскадирования), pg_receivewal, pg_basebackup могут использовать по одному слоту. При изменении значения требуется перезапуск экземпляра.

max_slot_wal_keep_size (по умолчанию -1 без ограничений) - максимальный размер журнальных файлов, который может оставаться в каталоге pg_wal после выполнения контрольной точки для слотов репликации. Если реплика использует слот репликации и не подсоединяется к мастеру, то журнальные файлы удерживаются мастером для такого слота. Если не установлено ограничения, то файлы журнала заполнят всю файловую систему и экземпляр аварийно остановится. Чтобы этого не допустить, стоит установить ограничение. Однако, реплике придется получать файлы журналов откуда-то еще или реплику придётся удалить. Если реплика больше не нужна, нужно не забыть удалить её слот. При изменении значения требуется перечитать конфигурацию.

walsender_timeout (по умолчанию 60 секунд) - задаёт период времени, по истечении которого неактивные соединения по протоколу репликации разрываются. При изменении значения требуется перечитать конфигурацию.

synchronous_standby_names и synchronous_commit - конфигурируют после создания реплик для гарантий защиты от потерь транзакций при потере мастера. Можно менять без рестарта экземпляра.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-replication.html 


Создание реплики

Создание реплики

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

При создании реплики утилитой pg_basebackup удобно:

1) использовать параметры -C (--create-slot) и -S (--slot=имя) для создания постоянного слота репликации. Через этот слот будут передаваться журналы утилите pg_basebackup, а после окончания её работы слот не будет удалён, он будет удерживать журнальные файлы, чтобы мастер их не удалил до подсоединения реплики.

2) использовать параметр -R (--write-recovery-conf) в файл postgresql.auto.conf реплики будут записаны параметры конфигурации:

а) primary_conninfo - адрес по которому pg_basebackup подсоединялся к мастеру. Параметр указывает адрес и параметры сетевого соединения, с которыми процесс walreceiver экземпляра реплики будет подсоединиться к экземпляру мастера. walreceiver подсоединяется к walsender на экземпляре мастера.

б) primary_slot_name имя слота репликации, который использовала утилита pg_basebackup и который удерживает журнальные файлы до подсоединения walreceiver реплики к мастеру. Параметр не действует, если кластер не является репликой или не задан primary_conninfo.

в) в PGDATA создаётся файл standby.signal наличие которого указывает процессу startup не завершать восстановление, а находиться в режиме постоянного восстановления, кластер не открывается на запись. При наличии файла recovery.signal действует standby.signal.

3) После создания реплики установить на ней значение параметра конфигурации cluster_name. Изменение значения требует перезапуск экземпляра реплики. Параметр устанавливает значение по умолчанию для опции application_name параметра primary_conninfo. application_name устанавливает название реплики, которое может использоваться на мастере в параметре synchronous_standby_names. Также значение cluster_name будет выводиться в названии серверных процессов экземпляра, что удобно для мониторинга. Если значение cluster_name не установлено или пусто, то для application_name используется значение walreceiver.

4) Проверить и если нужно поменять значения в файлах параметров postgresql.cong, pg_hba.conf Эти файлы копируются с мастера и могут не подходить к хосту реплики. Например, на хосте реплики может быть меньше физической памяти, которая не сможет вместить shared_buffers. Если реплика находится на том же хосте что и мастер, то нужно изменить параметр port.

5) Настроить службу для автоматического запуска экземпляра реплики и запустить экземпляр реплики.

Слоты репликации

Причин не использовать слоты репликации нет. Слот использует и утилита pg_receivewal и реплика. Слоты бывают трёх видов: физический, временный физический, логический. Логический используется для логической репликации изменений в таблицах двух основных кластеров. Временные слоты используются в процессе создания автономной резервной копии, обычно предназначенной для создания клона или восстановления на момент окончания резервирования. Для передачи (трансляции) журнальных записей на кластера-реплики используются физические слоты репликации.

Физический слот репликации удобно создавать при создании бэкапа который и будет представлять собой резервный кластер. Это позволит «бесшовно» (без потери журнальных файлов в промежутке времени между окончанием бэкапа и запуском экземпляра реплики) запустить экземпляр реплики. При запуске экземпляра реплики запускается процесс walreceiver, который принимает журнальные записи и сохраняет их в PGDATA/pg_wal реплики. Также запускается процесс startup, который накатывает содержимое директории PGDATA/pg_wal и периодически (параметр wal_retrieve_retry_interval) проверяет не появилось ли там что-то новое.

Функции работы с физическими слотами:

pg_create_physical_replication_slot('имя', false, false) - слоту нужно дать имя. второй параметр важен по умолчанию false - LSN резервируется при первом подключении клиента потоковой репликации.  Если true, то LSN для этого слота репликации должен быть зарезервирован немедленно. Третий параметр по умолчанию false - слот физический постоянный, если true то временный.

pg_drop_replication_slot('имя') - удаляет слот любого типа.

pg_copy_physical_replication_slot('имя', 'имя_создаваемого', false) - создаёт слот и инициализирует его LSN существующего слота. Используется, если при создании двух реплик используется один и тот же бэкап.

Список слотов репликации можно посмотреть в представлении pg_replication_slots.

Дополнительные параметры конфигурации на репликах

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

walreceiver_status_interval (по умолчанию 10 секунд) Обратная связь будут отправляться не чаще, чем раз в этот интервал. Горизонт событий баз данных на мастере будет сдвигаться не чаще чем этот интервал.

wal_retrieve_retry_interval (по умолчанию - 5 секунд). время ожидания репликой поступления журнальных данных из любых источников (потоковая репликация, архив журналов локальный pg_wal), прежде чем повторять попытку получения (walreceiver отправляет запрос walsender и ждёт ответа, startup выполняет restore_command, startup читает PGDATA/pg_wal)

recovery_min_apply_delay (по умолчанию ноль). Будет рассмотрен позже.

hot_standby по умолчанию on. Определяет можно ли будет подключаться к экземпляру и выполнять запросы (горячий резерв) или нельзя (тёплый резерв). Параметр играет роль только в режиме реплики или восстановлении. Значение влияет на поведение экземпляра при восстановлении и обслуживании реплики. Например, если hot_standby=off, то значение другого параметра recovery_target_action=pause действует как shutdown, а если hot_standby=on, то как promote. Параметр меняется только с перезапуском экземпляра. Если hot_standby=on, то действуют параметры:

hot_standby_feedback («обратная связь») - по умолчанию off. Устанавливает будет ли walsender реплики (в режиме hot_standby=on так как при off запросов на реплике нет) сообщать walsenderу, от которого получает журналы, данные о запросах, которые выполняет в данный момент. При каскадной репликации данные от всех реплик (в каскаде) передаются мастеру. Мастер удерживает «горизонт событий баз данных» по самому длительному запросу (или транзакции в режиме REPEATABLE READ) среди всех реплик, на которых включена обратная связь. Это приводит к тому, что устаревшие версии строк не удаляются не только (авто)вакуумом, но и механизмом HOT - Heap-Only Tuples, зато благодаря этому запросы не реплике не получают ошибку "snapshot too old" (слишком старая моментальная копия) и имеют возможность доработать и выдать все данные.

walreceiver_timeout (по умолчанию 60 секунд). walreceiver реплики может обнаружить отсутствие ответа от walsender, и заново переподсоединиться.

max_standby_streaming_delay и max_standby_archive_delay (по умолчанию равно 30 секунд). Максимально допустимое время задержки применения WAL.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY 

Горячая реплика

Физическая реплика обслуживается своим экземпляром. Реплика может использоваться для обслуживания команд не меняющих данные - запросов. При переносе читающей логике стоит учитывать, что гарантировать актуальность возвращаемых репликой данных нельзя. Если параметр конфигурации на мастере synchronous_commit установлен в значение remote_apply, то реплика своим сессиям может отдавать (гарантировать такое поведение нельзя) данные раньше чем мастере. То есть если есть две сессии от клиента к мастеру и реплике, в этих сессиях по времени одновременно даётся команда SELECT к строкам, которые только что были изменены транзакцией в параллельной сессии мастера, сессия с репликой может выдать измененные этой транзакций данные, а сессия мастера не выдать. Гарантировать синхронность отдачи тех же самых данных нельзя. Переносить на реплику всю читающую нагрузку не стоит. На реплику можно перенести часть логики приложения, которая строит отчёты и выполняет аналитические запросы. Это запросы, длительность выполнения которых существенно превышает репликационный лаг (задержку в передаче и накате журнальных записей) и он не играет роли для логики приложения.

По умолчанию параметр конфигурации hot_standby=on и физическая реплика работает в режиме горячего резерва - может обслуживать команды, не меняющие данные. Например, команды выборки SELECT, WITH, COPY TO, а также команды BEGIN TRANSACTION, COMMIT, ROLLBACK - эти команды нужны, чтобы иметь возможность выполнять запросы на один момент времени, что реализуется открытием транзакции на реплике в режиме REPEATABLE READ Уровень SERIALIZABLE не поддерживается и не отличается для чтения от REPEATABLE READ:

ERROR:  cannot use serializable mode in a hot standby
HINT:  You can use REPEATABLE READ instead.

Результаты команд COMMIT и ROLLBACK не будут отличаться, они используются только для закрытия транзакции которая ничего не меняла. Использование временных таблиц невозможно.

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/hot-standby.html 

Обратная связь

По умолчанию hot_standby_feedback=off и мастер не принимает во внимание, что на репликах выполняются команды SELECT. Это значит, что на мастере могут выполняться команды DROP, передаваться на реплики, применяться процессом startup и SELECT обращавшийся к объекту его не найдёт и выдаст ошибку. А после DROP DATABASE на мастере и проведения этой команды на реплике, сессии на реплике с этой базой данных будут прерваны. Команды изменения объектов на мастере выполняются нечасто, да и смысла дорабатывать запросам если объект решили удалить нет. Практическое влияние на запросы на реплике оказывает вакуумирование (в том числе автоматическое) на мастере, вычищающее старые версии строк. Старые версии строк образуются после их удаления или обновления, но не после вставок. Запрос на реплике может прерваться, даже если вакуум не отрабатывал на таблице, а по причине обновления HOT (Heap-Only tuples).

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

  1. установить значения параметров max_standby_streaming_delay и max_standby_archive_delay в длительность самого длинного запроса. Если запрос превысит это время, то он прервется с ошибкой не всегда, а только при наличии конфликта. Задержка в применении конфликтующих журнальных записей может увеличить отставание реплики от мастера («лаг») вплоть до значений этих параметров. Все сессии на реплике будут выдавать данные с задержкой.  Также если захочется сделать из реплики мастер, возможна задержка на применение журнальных записей для устранения лага.
  2. включить обратную связь. Это повлияет на мастер - он не сможет очищать старые версии строк, так как запросы на репликах будут удерживать горизонт событий баз данных мастера. Удержание горизонта влияет на вакуумирование и оптимизацию HOT.

Мониторинг горизонта событий

Проверять сдвигается ли горизонт событий баз данных важно для оценки того сможет ли автовакуум эффективно очищать старые версии строк, а HOT выполнять очистку внутри страниц и оценивать последствия включения обратной связи. Для мониторинга удобнее использовать Платформу Tantor. Информацию можно получить из представлений системного каталога.

Количество отменённых запросов в базах данных реплики с момента сброса статистики можно просмотреть в представлении pg_stat_database_conflicts на реплике.

Горизонт баз данных кластера в количестве номеров транзакций, отстоящих от текущей:
SELECT datname, greatest(max(age(backend_xmin)), max(age(backend_xid))) FROM pg_stat_activity WHERE backend_xmin IS NOT NULL OR backend_xid IS NOT NULL group by datname order by datname;

Длительность самого долгого запроса или транзакции баз данных кластера:
select datname, extract(epoch from max(now()-xact_start)) from pg_stat_activity WHERE backend_xmin IS NOT NULL OR backend_xid IS NOT NULL group by datname order by datname;

Представление pg_replication_slots содержит состояние всех слотов репликации. Столбец xmin содержит идентификатор старейшей транзакции, для которой должен удерживаться горизонт. Пример запроса:
select max(age(xmin)) from pg_replication_slots;

Представление pg_stat_replication на мастере содержит по одной строке для каждого walsender. Столбец backend_xmin содержит идентификатор старейшей транзакции ("xmin") реплики, если включена обратная связь (hot_standby_feedback=on). Пример запроса:

SELECT backend_xmin, application_name FROM pg_stat_replication ORDER BY age(backend_xmin) DESC;

В самих репликах искать процессы, выполняющие команды, удерживающие горизонт можно так же, как и на мастере - запросом к pg_stat_activity:

SELECT backend_xmin, backend_xid, pid, datname, state FROM pg_stat_activity WHERE backend_xmin IS NOT NULL OR backend_xid IS NOT NULL ORDER BY greatest(age(backend_xmin), age(backend_xid)) DESC;

https://docs.tantorlabs.ru/tdb/ru/15_6/se/monitoring-stats.html 

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

Часть параметров требует внимания. Если менять значения этих параметров на мастере, то на репликах эти значения должны соответствовать значениям на мастере. Так как роли мастер-реплика могут меняться, стоит значения этих параметров делать одинаковыми на всех кластерах, чтобы не следить за значениями после смены ролей. Если нужно увеличить значения этих параметров, сначала нужно увеличить на всех репликах, а затем внести изменения на мастере. Если нужно уменьшить значения этих параметров, сначала уменьшить на мастере, а затем уже менять значения на репликах.

Изменения в этих параметрах записываются в WAL. Если в процессе чтения принятых WAL процесс startup реплики обнаружит, что значение на мастере стало больше, чем в конфигурации его экземпляра, то если реплика открыта для чтения (параметр hot_standby=on), то в лог кластера запишется предупреждение и наложение журнальных записей приостановится. Если реплика не допускает подключений (hot_standby=off), то экземпляр реплики остановится и прекратит принимать журнальные записи, что может привести к проблеме при синхронной репликации.

Список параметров:

1) max_connections, max_prepared_transactions, max_locks_per_transaction эти параметры ограничивают максимальное количество блокировок объектов

2) max_walsenders 

3) max_worker_processes 

https://docs.tantorlabs.ru/tdb/ru/15_6/se/hot-standby.html 

Смена ролей

Смена ролей мастер-реплика

В физической репликации у одного из кластеров «роль» мастера (ведущего, основного), у остальных роли резервных серверов (реплик, ведомых). Менять роли можно:

Перед проведением процедуры нужно:

  1. исключить или минимизировать потерю транзакций. Для защиты от потери можно до сбоя настроить синхронную репликацию с подтверждением репликами транзакций и переключиться на ту реплику, которая имеет наибольший принятый и применённый LSN. Если синхронная репликация не использовалась, то стоит найти журнальные файлы мастера. Определить файл журнала, в который писал экземпляр мастера перед повреждением можно по управляющему файлу мастера утилитой pg_controldata или другими способами. Этот файл и другие, если они не были переданы на реплику можно скопировать в директорию PGDATA/pg_wal реплики и убедиться, что журнальные записи из него применены.
            При синхронной репликации настройка может быть такой что транзакции подтверждает одна из реплик. При повреждении мастера может случиться так, что только одна реплика получила последнюю журнальную запись, а другие не получили. Если сделать мастером реплику не получившую последнюю журнальную запись, то могут быть потери транзакций. Выяснить какая из реплик получила последнюю журнальную запись мастеру можно с помощью функций:
    pg_last_wal_receive_lsn() - последний полученный LSN на реплике
    pg_last_wal_replay_lsn() - журнальная запись, которая была восстановлена последней. Если pg_is_in_recovery() возвращает true значит это последняя наложенная журнальная запись На мастере функция выдаёт LSN на котором экземпляр мастера открывался после восстановления, а если он был корректно закрыт, то возвращает NULL. Мастером нужно назначать реплику, у которой больший LSN.
  2. В каждый момент времени должен быть только один мастер. Если клиентам доступны два мастера и они принимают изменения («split brain») от клиентов, то разобрать транзакции будет сложно. Чтобы избежать доступности двух мастеров нужно остановить экземпляр мастера перед тем как дать сигнал одной из реплик стать мастером.

Повышение реплики до мастера

Для того чтобы реплика стала мастером (promote, продвинуть или повысить) можно двумя способами:

1) выполнить pg_ctl promote

2) вызвать функцию pg_promote(boolean, integer). Первый параметр - нужно ли ждать завершения операции (по умолчанию true), второй параметр максимальное количество секунд ожидания (по умолчанию 60). Возвращает true если операция продвижения успешно выполнена.

Если удалить файл standby.signal и перезапустить экземпляр реплики, то перехода на новую линию времени не будет. В этом случае утилитой pg_rewind на практике не удастся воспользоваться и придется пересоздавать бывший мастер. Удаление файла standby.signal может рассматриваться только как способ сменить роли с корректной остановкой мастера перед продвижением реплики.

После того как появится новый мастер можно будет поменять значения параметра primary_conninfo других реплик и бывшего мастера. Создать слоты репликации на новом мастере. Сделать из бывшего мастера реплику, для этого создать файл standby.signal. Если экземпляр бывшего мастера был остановлен корректно и файлы кластера не повреждены, то достаточно запустить экземпляр кластера не забыв создать файл standby.signal. Если бывший мастер был остановлен некорректно, то его скорее всего захочется восстановить. Восстановить можно пересоздав кластер: сделав бэкап утилитой pg_basebackup -R. Также можно использовать утилиту pg_rewind, если продвижение нового мастера было выполнено с переходом на новую линию времени.

Файлы истории линий времени

Каждый раз, когда создаётся новая линия времени, создаётся файл истории линий времени, сохраняющий метки от какой линии времени ответвилась новая линия и когда.

Новая линия времени создаётся при повышении реплики до мастера; при восстановлении из бэкапа на момент времени в прошлом, который можно задать одним из параметров: recovery_target, recovery_target_lsn, recovery_target_name,
recovery_target_time, recovery_target_xid
.

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

Файл истории линий времени - это текстовый файл небольшого размера в директории PGDATA/pg_wal с названием 0000000N.history. Можно добавлять в файл истории комментарии о том, как и почему была создана эта конкретная линия времени.

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

Пример содержимого файла 00000003.history

1       116/E30150E8    no recovery target specified

2       116/E30161E8    no recovery target specified

Удалять эти файлы не стоит. Пример ошибок связанных с отсутствием файлов:

pg_basebackup: could not send replication command "TIMELINE_HISTORY": ERROR:  could not open file "pg_wal/00000002.history": No such file or directory

pg_rewind -D /var/lib/postgresql/tantor-se-16-replica/data1 --source-server='user=postgres port=5432'

pg_rewind: connected to server

pg_rewind: error: could not open file "/var/lib/postgresql/tantor-se-16-replica/data1/pg_wal/00000004.history" for reading: No such file or directory

Запуск экземпляра после перехода на новую линию:

pg_ctl start -D /var/lib/postgresql/tantor-se-16-replica/data1

...

LOG:  unexpected timeline ID 2 in WAL segment 0000000400000116000000E3, LSN 116/E3016000, offset 90112

LOG:  invalid checkpoint record

PANIC:  could not locate a valid checkpoint record

LOG:  startup process (PID 7638) was terminated by signal 6: Aborted

https://docs.tantorlabs.ru/tdb/ru/15_6/se/continuous-archiving.html#BACKUP-TIMELINES 

Утилита pg_rewind

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

Для работы утилиты существенным является наличие ветвления линий времени. Утилита ищет файл 0000000N.history (содержит историю создания линий времени) обоих кластеров с целью найти точку, в которой линии времени двух кластеров разошлись. Затем читает журнальные файлы в PGDATA/pg_wal начиная с последней контрольной точки перед моментом, когда история линии времени разошлась и до текущего файла журнала того кластера, чью директорию будет синхронизировать («целевой» кластер). По журнальным записям определяет все блоки, в которые были внесены изменения. Затем копирует эти блоки с другого кластера.

Дальше утилита копирует все файлы, находящиеся в PGDATA (и табличных пространств), включая новые файлы данных, файлы журналов, pg_xact, файлы параметров, произвольные файлы. Директории pg_dynshmem, pg_notify, pg_replslot, pg_serial, pg_snapshots, pg_stat_tmp, pg_subtrans, pgsql_tmp, файлы backup_label, tablespace_map, pg_internal.init, postmaster.opts и postmaster.pid не копируются. Утилита создаёт файл backup_label для перехода к накату журнала начиная с контрольной точки до точки расхождения и устанавливает в файле pg_control LSN начала согласованного состояния. Утилита копирует все файлы параметров, которые находятся в PGDATA. Если содержимое файлов параметров важно, то стоит их сохранить до запуска утилиты, чтобы после ее работы восстановить.

Обычно утилита используется для того, чтобы вернуть в работу бывший мастер в результате незапланированной смены ролей (failover). Если бывший мастер не успеет передать хотя бы одну журнальную запись на реплику, которая станет мастером, то бывший мастер не может работать репликой. Чтобы полностью не пересоздавать бывший мастер и используется утилита pg_rewind.

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

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

Использование параметров -R --source-server='адрес' упрощает конфигурирование: создаётся файл standby.signal и в конец postgresql.auto.conf добавляется параметр primary_conninfo с  параметрами подключения.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/app-pgrewind.html 

Процессы экземпляра реплики

На экземпляре реплики присутствуют процессы:

  1.  postgres - основной процесс. прослушивает сокеты, запускает процессы.
  2.  Checkpointer - контрольные точки инициируются только на мастере. На реплике реплике при получении журнальной записи о контрольной точке выполняется «точка рестарта».

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

  1.  background writer - записывает грязные страницы из буферного кеша на диск.
  2.  startup - накатывает журнальные записи.
  3.  walreceiver, который принимает журнальные данные от процесса walsender мастера.
  4.  Могут присутствовать процессы расширений, например, stats collector, а также серверные процессы, обслуживающие сессии созданные с репликой.

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

Отложенная репликация

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

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

Приём журнальных записей репликой (процесс walreceiver) осуществляется без задержки. Журнальные файлы будут храниться в PGDATA/pg_wal реплики до тех пор, пока они не будут применены процессом startup. Чем больше задержка, тем больший объём WAL-файлов нужно накапливать и тем больше дискового пространства потребуется для каталога PGDATA/pg_wal на реплике.

Важно помнить, что при использовании обратной связи (параметр hot_standby_feedback) мастер не сможет очистить старые версии строк с как минимум на установленную задержку (плюс длительность запросов на реплике). Нужно с осторожностью использовать обратную связь при использовании задержки.

Также если synchronous_commit=remote_apply на мастере и реплика единственная в конфигурации или должна использоваться для подтверждения транзакций, то все транзакции будут подвисать на время установленной задержки.

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

Отложенная репликация управляется функциями. Например, pg_wal_replay_pause() позволяет приостановить восстановление. Его используют если на мастере прошли нежелательные изменения и нужно принять решение что делать - выгрузить данные из реплики или подкатив журнальные записи до желаемого момента сделать из реплики мастер.


page_repair

Модуль page_repair доступен во всех версиях СУБД «Tantor».

select * from pg_available_extensions where name like '%repair%';

    name     | default_version | installed_version |         comment          

-------------+-----------------+-------------------+--------------------------

 page_repair | 1.0             |                   | Individual page reparing

postgres=# load 'page_repair';

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

Расширение page_repair предоставляет функцию pg_repair_page (table regclass, block_number bigint, connstr text).

Ведомый сервер, к которому можно подключиться с помощью connstr, должен иметь тот же системный идентификатор, что и сервер, на котором выполняется данная функция. Эта функция может быть выполнена на ведущем сервере и только суперпользователем. Если вы хотите восстановить другие объекты, такие как карта свободного пространства, карта видимости, вы можете использовать функцию pg_repair_page (table regclass, block_number bigint, connstr text, forkname text), где forkname может быть main, fsm или vm.

Функция pg_repair_page устанавливает AccessExclusiveLock на целевую таблицу и может ожидать, пока ведомый сервер не сравняется с ведущим сервером. Эта функция не пытается восстановить страницу, которая отмечена как грязная в общем буфере, поскольку грязная страница будет выгружена на диск и тем самым могла бы исправить поврежденную страницу.

Восстановление повреждённых страниц

В СУБД Tantor всех сборок имеется расширение page_repair. При появлении поврежденной страницы данных на мастере, есть возможность забрать образ страницы с реплики, если она не повреждена на этой реплике. В базе данных мастера нужно установить расширение. Пример команды:

CREATE EXTENSION page_repair;

Расширение содержит две функции:

1) pg_repair_page(table regclass, block_number bigint, connstr text) Параметры функции: table имя таблицы, block_number номер поврежденного блока

connstr строка соединения к резервному серверу. Пример строки соединения можно взять из параметра конфигурации primary_conninfo на любой из реплик. На мастере этот параметр можно установить заранее на случай смены ролей.

2) pg_repair_page(table regclass, block_number bigint, connstr text, fork text)

fork - название форка в котором нужно восстановить блок: 'main', 'fsm', 'vm'.

Функция pg_repair_page запрашивает монопольную блокировку ACCESS EXCLUSIVE на объект, в котором будет восстанавливаться блок и ждёт, пока реплика не наложит журнальные записи мастера убрав отставание (лаг) от мастера. Если планируется восстановить несколько страниц, то можно получить блокировку заранее командой LOCK TABLE.

https://docs.tantorlabs.ru/tdb/ru/15_6/be/page_repair.html 

standby fadvise

Для всех версий СУБД «Tantor»  доступна оптимизация  и ускорение процесса восстановления каскадной репликации (standby fadvise).

Патч для повышения производительности путем добавления предварительного чтения для WAL (Write-Ahead Log) блоков в PostgreSQL, используя системный вызов `posix_fadvise()` с параметром `POSIX_FADV_WILLNEED`. Это указывает операционной системе, что определенные блоки данных скоро потребуются, что позволяет ей оптимизировать чтение с диска, упреждающе загружая данные в кэш.

Также в этом патче добавляется новое событие ожидания `WAIT_EVENT_WAL_PREFETCH` для отслеживания времени, затраченного на предварительное чтение WAL. Это позволяет администраторам БД более детально анализировать производительность системы и определять, улучшает ли предварительное чтение WAL общую производительность

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

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

pg_cluster

Во всех версиях СУБД «Tantor» доступен pg_cluster.

Дополнительно поставляемая с СУБД Tantor программа pg_cluster - это набор инструкций Ansible playbook для создания кластера PostgreSQL с высокой доступностью на базе Patroni. Минимизирует трудозатраты администратора.

Страница с описанием утилиты:

https://github.com/TantorLabs/pg_cluster/ 

Логическая репликация

Обзор архитектуры публикация-подписка

Логическая репликация

При репликации происходит захват, передача, применение изменений в строках таблиц. При физической репликации изменения отслеживаются и применяются на физическом уровне - уровне файлов, страниц. При логической репликации отслеживаются изменения на уровне таблиц и их строк, то есть логических объектов. В логической репликации изменения применяются командами SQL, для строк - построчно.

При настройке логической репликации определяются наборы «таблиц-источников», изменения в которых нужно реплицировать. Эти наборы таблиц включаются в объект базы данных «публикация». Можно добавлять или исключать таблицы из «публикации» не пересоздавая её. Публикация - локальный объект базы данных и в неё можно включить только таблицы, находящиеся в её базе данных.

Захватываются не сами команды SQL, которые вносили изменения, а их последствия: по каждой строке, которую затронула команда захватывается идентификатор строки, тип действия со строкой (удалить, вставить, изменить) и значения полей, затронутых командой в этой строке. Такую логику называют "row-based replication". Существуют архитектуры "statement-based replication" (репликация команд), но этот тип репликации не используется для команд обрабатывающих строки таблиц, так как имеет побочные эффекты.

Логическая и физическая репликация могут работать одновременно.

Логическая репликация использует архитектуру «публикации» (источник) и «подписки» (приёмник). При настройке репликации создаются одноимённые объекты в базах данных.

Логическая репликация развивается, в ней появляются новые возможности.

Новые возможности в 15 версии:

https://docs.tantorlabs.ru/tdb/ru/15_6/se/release-15.html#id-1.11.6.15.5.4.3 

Новые возможности в 16 версии:

https://postgrespro.com/docs/postgresql/16/release-16#RELEASE-16-HIGHLIGHTS 

Применение логической репликации

Примеры использования, помимо перечисленных на слайде:

https://docs.tantorlabs.ru/tdb/ru/15_6/se/logical-replication.html 

Физическая и логическая репликация

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

Недостатки по сравнению с физической:

https://docs.tantorlabs.ru/tdb/ru/15_6/se/logical-replication-restrictions.html 


Идентификация строк

Идентификация строк

Логическая репликация реплицирует не текст команд SQL выполняемых над таблицами включенными в публикацию, а изменения в строках таблиц. Для INSERT идентификации не нужно и REPLICA IDENTITY может иметь любое значение. Для UPDATE и DELETE (и MERGE если хоть одна строка изменится или удалится) нужно идентифицировать строки, в которые будет вноситься изменения. Для идентификации нужно захватить и передать значения в столбцах даже если в самой команде на источнике эти столбцы не упоминались. Иногда это называют захватом значений полей до изменения (before image). Однако before image более широкое понятие - они могут использоваться для процедур разрешения конфликтов и для этого в before image могли бы включаться не только идентифицирующие строку столбцы, но и любые другие. В текущей версии функционала автоматического разрешения конфликтов нет и before image используются с целью идентификации строки.

Чтобы можно было реплицировать UPDATE и DELETE, а они реплицируются построчно, в таблицах публикации должен быть настроен «репликационный идентификатор», чтобы идентифицировать строки для изменения или удаления на стороне подписчика.

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

Вместо первичного ключа (в том числе составного) в качестве репликационного идентификатора можно назначить любой из уникальных индексов на таблице. Первичный ключ отличается от уникального тем, что в первичном ключе есть ограничение NOT NULL на всех столбцах ключа. При использовании уникальных индексов нужно добавить это ограничение на столбцы которые используются в этом ограничении. Использовать уникальные индексы имеет смысл, только если в таблице нет первичного ключа.

Без первичных ключей и уникальных индексов можно реплицировать UPDAТE и DELETE, но тогда репликационным идентификатором придётся назначить все столбцы таблицы. Если в публикацию, в которой реплицируются операции UPDATE и DELETE, добавляется таблица без задания REPLICA IDENTITY, то транзакции с UPDATE и DELETE на источнике (а не на подписчиках) будут завершены с ошибкой.

Способы идентификации строк

Команды INSERT смогут выполняться без ошибок, им идентификатор не нужен и может быть любым. Одно из возможных значений REPLICA IDENTITY NOTHING. В документации описывается как «Записи не содержат информации о старой строке. Records no information about the old row» то есть в терминах «before image» и означает, что значения столбцов помимо указанных в команде не захватываются, но команды UPDATE и DELETE блокируются на источнике. Пример ошибки на источнике:

ALTER TABLE t REPLICA IDENTITY NOTHING;

UPDATE t SET t='b' WHERE id=2;

ERROR:  cannot update table "t" because it does not have a replica identity and publishes updates

HINT:  To enable updating the table, set REPLICA IDENTITY using ALTER TABLE

Значение NOTHING установлено по умолчанию для таблиц системного каталога (находящиеся в схеме pg_catalog).

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

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

Список таблиц в базе данных, которые не могут реплицировать UPDATE и DELETE, пока не будет создан первичный ключ или задан способ идентификации:

SELECT relnamespace::regnamespace||'.'||relname "table"

 FROM pg_class

 WHERE relreplident IN ('d','n') -- d первичный ключ, n никакие

  AND relkind IN ('r','p') -- r таблица, p секционированная

  AND oid NOT IN (SELECT indrelid FROM pg_index WHERE indisprimary)

  AND relnamespace <> 'pg_catalog'::regnamespace

  AND relnamespace <> 'information_schema'::regnamespace

ORDER BY 1;


Настройка

Шаги по созданию логической репликации

Для настройки логической репликации нужно:

  1.  Проверить что параметр wal_level=logical на кластере-источнике
  2.  Выбрать таблицы, которые будут включены в публикацию. Таблицы должны иметь первичный ключ. Если первичного ключа нет, то желательно проверить наличие уникального, не частичного, не отложенного индекса и наличие ограничения целостность NOT NULL для столбцов этого индекса и дать команду ALTER TABLE имя REPLICA IDENTITY USING INDEX имя_индекса; Если эти условия не выполняются, можно дать команду ALTER TABLE имя REPLICA IDENTITY FULL; но в этом случае при изменении или удалении строк в журнал будут записываться старые значения всех столбцов этих строк, а размер строк может быть большим.
  3.  На базе данных в этом или другом кластере создать таблицы, которые будут принимать изменения. Скрипт создания таблиц можно получить утилитой pg_dump с параметром --schema-only. Функционал логической репликации не имеет возможности скопировать определения таблиц.
            Команды DDL не реплицируются, определения и набор таблиц не синхронизируются.  Изначальный набор таблиц в публикации можно скопировать утилитой
     pg_dump с параметром --schema-only. Последующие изменения набора таблиц и их определений нужно будет синхронизировать вручную. Схемы, и таблицы не обязательно должны быть абсолютно идентичными в базах данных публикации и подписчиков. Если определения таблиц в базе данных публикации не меняются, логическая репликация работает надёжно. Если меняется определение таблицы в публикующей базе данных, и команда на подписчике не может применяться, то выдаётся ошибка, репликация по всей подписке приостанавливается и можно провести вручную изменение определения таблицы и репликация восстановится без потерь данных. Во многих случаях можно сначала поменять определения таблиц на подписчике, а потом на публикуемой таблице и репликация не будет приостанавливаться.
  4.  На базе данных где находятся выбранные для репликации таблицы создать публикацию или публикации командой CREATE PUBLICATION. Публикация может включать в себя таблицы только своей базы данных
  5.  На базе с таблицами в которые будут реплицироваться изменения создать подписку или подписки командой CREATE SUBSCRIPTION.

Создание публикации

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

Почему не создать одну публикацию? Средний размер строк в таблицах может отличаться. Если есть таблицы со строками большого объема, то изменения в этих строках будут передаваться подписчикам, а пропускная способность сети может быть ограничена и обработка и применение к таблицам подписки всех переданных изменений по всем таблицам при большом объеме изменений может в какие-то диапазоны времени создавать значительный репликационный лаг. Если разбить таблицы например на две публикации, в одну включить таблицы с небольшими строками, то по ним репликационный лаг может быть меньшим и колебаться в небольших пределах. Универсальных средств определить как разбивать таблицы на несколько публикаций нет, нужно знать как приложение работает с таблицами.

Имя публикации должно быть уникальным в пределах своей базы данных. Создание публикации не запускает репликацию. Оно только определяет логику группировки и фильтрации для будущих подписчиков. Все таблицы, добавленные в публикацию, которая публикует операции UPDATE и/или DELETE, должны иметь определенный REPLICA IDENTITY. В противном случае эти операции будут запрещены для этих таблиц. Для команды MERGE и , публикация будет публиковать INSERT, UPDATE или DELETE для каждой вставленной, обновленной или удаленной строки. Команды COPY публикуются в виде операций INSERT. Для команд MERGE и INSERT.. ON CONFLICT публикация будет публиковать фактическую операцию с каждой строкой.

В команде CREATE PUBLICATION можно указать:

  1.  FOR ALL TABLES - реплицирует изменения для всех таблиц в базе данных, включая таблицы, созданные в будущем.
  2.  FOR TABLES IN SCHEMA - реплицирует изменения для всех таблиц в указанном списке схем, включая таблицы, созданные в будущем.
  3.  FOR TABLE - список таблиц. Если перед именем таблицы указано слово ONLY, то в публикацию добавляется только эта таблица. Если слово ONLY не указано, то в публикацию добавляется таблица и все ее наследники. После имени таблицы можно указать названия столбцов, тогда реплицироваться будут только значения этих столбцов (и столбцы - идентификаторы строк). По умолчанию реплицируются все столбцы, включая те которые будут добавлены в будущем. Опцией WHERE можно задать фильтр чтобы публиковать изменения не во всех строках, а только тех изменений, которые удовлетворяют заданному условию. Список таблиц может быть пуст. Таблицы можно добавить позже командой ALTER PUBLICATION.
  4.  В опции WITH () можно указать значения для двух опций. В опции publish какие действия со строками будут реплицироваться: insert, update, delete, truncate. Для секционированных таблиц есть опция publish_via_partition_root.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-createpublication.html 

Подписка

После создания публикации можно создавать подписки на базах данных с таблицами куда будут реплицироваться изменения. Подписки добавляются командой CREATE SUBSCRIPTION и могут быть приостановлены/возобновлены в любой момент командой ALTER SUBSCRIPTION, а также удалены командой DROP SUBSCRIPTION.

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

Таблицы публикации сопоставляются с таблицами подписчика по именам. Репликация в таблицы с другими именами на стороне подписчика не поддерживается. Столбцы таблиц также сопоставляются по именам. Порядок столбцов в таблице подписчика может отличаться от порядка столбцов в публикации. Также могут не совпадать типы столбцов; достаточно только возможности преобразования текстового представления данных в целевой тип. Целевая таблица может также содержать дополнительные столбцы, отсутствующие в публикуемой таблице. Такие столбцы будут заполнены значениями по умолчанию, заданными в определении целевой таблицы или триггерами.

Каждая активная подписка получает изменения из своего слота репликации созданного на публикующей стороне. Подписка и слот логической репликации могут управляться отдельно друг от друга. Например, нужно перенести таблицы подписчика другую базу данных (в том же кластере или другом) и активировать подписку там. Сначала командой ALTER SUBSCRIPTION разрывается связь подписки со слотом. Потом удаляется подписка, слот остаётся. Потом перегружаются данные в другую базу данных и создаётся подписка с параметром create_slot=false, и связывается с существующим слотом.

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se/logical-replication-subscription.html 

Создание подписки

Команда CREATE SUBSCRIPTION создаёт подписку. Имя подписки уникально в пределах базы данных, где она создана. Параметры создания подписки:

  1.  CONNECTION 'строка' подключения к базе данных публикации
  2.  PUBLICATION имена публикаций через запятую
  3.  WITH (параметр= значение, ...). Имеется больше десятка параметров, они описаны в документации. Основные параметры:

connect равно true по умолчанию. Нужно ли подключаться к базе данных публикации. Если поставить false, то параметры create_slot, enabled, copy_data тоже будут false

create_slot = true по умолчанию. Создавать ли слот логической репликации

enabled = true по умолчанию. Запускать ли подписку или оставить неактивной

copy_data = true по умолчанию.  Будут ли копироваться существующие строки таблиц на которые оформляется подписка. При больших объемах данных копирование в один поток может занять значительное время

slot_name по умолчанию такое же как имя подписки. Стоит установить правила именования подписок, чтобы их имена были уникальными во всех кластерах. Если установить значение NONE, то нужно установить  enabled=false и create_slot=false

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

streaming = off по умолчанию, данные начинают передаваться подписке после фиксации транзакции.  При значении on данные транзакций начинают передаваться немедленно и записываются на кластере с подпиской во временные файлы, а начинают применяться после фиксации транзакции в публикующей базе. При значении parallel, изменения начинают применяться немедленно фоновым процессом parallel worker. Если свободного процесса нет (их количество ограничивают параметры max_logical_replication_workers и max_worker_processes), то поведение как у значения on. Если транзакции обрабатывают большие объемы данных установка этих значений позволяет уменьшить репликационный лаг, так как изменения начинают передаваться и применяться без задержки. Уменьшение лага, которое можно ожидать 30-50%.

synchronous_commit = off по умолчанию. Переопределяет значение одноимённого параметра конфигурации для транзакций которыми применяются изменения в базе подписки. Значение off безопасно для логической репликации, так как если подписчик потеряет транзакции, то они будут повторно переданы.

disable_on_error = false по умолчанию. Если установить true, то в случае обнаружения ошибки на стороне подписки, подписка переводится в состояние disabled. Если true, то делаются периодические попытки применить изменение, вдруг ошибка исчезнет

origin = any по умолчанию, публикация отправляет все изменения. Если используется двунаправленная репликация, то нужно установить origin=NONE для предотвращения  зацикливания («ping  pong», эхо).

https://docs.tantorlabs.ru/tdb/ru/15_6/se/sql-createsubscription.html 


Особенности

Нагрузка на экземпляр

Для каждой подписки на кластере-источнике запускается процесс walsender, по одному процессу для каждой подписки, которая в свою очередь использует отдельный слот репликации. Использование слота логической репликации обязательно. Их количество ограничивают параметры max_wal_senders и max_replication_slots. Изменение параметров требует перезапуск экземпляра. Процесс walsender читает файлы журнала, но в отличие от физической репликации не просто передаёт журнальные записи, а обрабатывает. Сначала процесс walsender накапливает в своей локальной памяти (reorderbuffer) изменения, сделанные каждой транзакцией. По умолчанию подписка создаётся с параметром streaming=off. Это означает, что должны реплицироваться только зафиксированные транзакции, для этого и используется буфер. Если объем изменений превысит значение logical_decoding_work_mem (по умолчанию консервативное значение 64Мб), то изменения начнут записываются в файлы директории PGDATA/pg_replslot/имя_слота. Также, если накопленное количество изменений в одной транзакции превысит 4096, то изменения этой транзакции тоже начнут записываться в файл. Значение выбрано достаточно большим, чтобы отсечь OLTP транзакции от транзакций с массовыми изменениями строк.

Логику буферизации можно поменять параметром конфигурации debug_logical_replication_streaming.

Накопленные в буфере данные по зафиксированным транзакциям (или незафиксированным при значениях streaming = on или parallel) передаются модулю вывода pgoutput. Модуль - это отдельный процесс, а код, который выполняет walsender. На работу этого модуля влияет номер основной версии программного обеспечения подписчика, параметр binary подписки (по умолчанию binary=off и используется преобразование изменений в транзакции в виде текстовых строк); streaming - при значении parallel передаётся дополнительная информация, origin (именно модуль фильтрует транзакции, порождённые процессами логической репликации) и другие параметры, которые задаются в свойствах подписки.

https://postgrespro.com/docs/postgresql/16/protocol-logical-replication#PROTOCOL-LOGICAL-REPLICATION-PARAMS 

Получение журнальных данных с реплики

Знание архитектуры логической репликации позволяет понимать трудоёмкость обработки данных на кластере-источнике, оценивать нагрузку на память, процессора (из-за большого количества процессов walsender) и дисковый ввод-вывод (чтение файлов журналов каждым из процессов walsender и запись в файлы директории PGDATA/pg_replslot). Нагрузка на хост, где работают процессы walsender, обслуживающие логическую репликацию, может быть существенной.

Если имеются физические реплики, то разумно перенести на сторону физических реплик всю работу, выполняемую процессами walsender. В архитектуре логической репликации постгрес основная обработка изменений выполняется walsender, а не на стороне приёмника.

Для получения данных с физической реплики нужно:

  1. В публикации указать в параметре подсоединения адрес реплики.
  2.  Реплика должна быть горячей (hot_standby=on).
  3. Включить обратную связь (hot_standby_feedback=on), иначе автовакуум может очистить в таблицах системного каталога нужные подписке версии строк и слот перестанет работать, репликация остановится.
  4.  Между репликой и мастером нужно использовать физической слот репликации.

Если в процессе выполнения команды CREATE SUBSCRIPTION долго не возвращается промпт можно на мастере выполнить функцию: select pg_log_standby_snapshot(). Для создания логического слота репликации нужен моментальный снимок (список всех активных транзакций на мастере). Реплика не имеет доступа к транзакциям на мастере и вынуждена ждать пока процесс checkpointer или bgwriter на мастере не запишут в журнал снимок.

Если после вызова функции промпт не возвращается, то значить используется начальная синхронизация строк таблиц (copy_data = true) и объем данных большой. Начальная синхронизация выполняется через дополнительно создаваемый слот логической репликации, который будет удалён когда копирование строк завершится.

Что произойдёт в случае, если мастер выйдет из строя и реплику сделают мастером? Логическая репликация продолжит работать без изменений. Слоты репликации (логические и физические) в СУБД Tantor сохраняются после смены ролей.

https://postgrespro.com/docs/postgresql/16/logicaldecoding-explanation 

Конфликты

Для каждой подписки запускается процесс logical replication worker. Этот процесс подсоединяется к процессу walsender по протоколу репликации и принимает поток декодированных модулем вывода изменений. Изменения проводятся командами INSERT, UPDATE, DELETE построчно: используя идентификатор строки REPLICA IDENTITY. Если генерируемые команды не могут внести изменения из-за нарушения ограничений целостности или по другой причине (например, срабатывает триггер и генерирует необработанное исключение, нет привилегий выполнить команду), то репликация во всей подписке приостанавливается и возобновится после устранения проблемы если значение параметра подписки disable_on_error=false. Возникновение ошибки называется «конфликт».

Если выполняется команда UPDATE или DELETE, а строка отсутствует (то есть обновлено или удалено ноль строк), то это не ошибка и конфликта нет, команда пропускается и репликация продолжает работать.

Функционала создать правила, по которым конфликт разрешается (автоматическое разрешения конфликтов) нет. Информацию об ошибке можно увидеть в логе кластера. В ошибке указан LSN содержащий COMMIT транзакции, к которой относится изменение, нарушающее ограничение.

Устранить конфликт можно вручную изменив данные или определение объекта: изменив строку с которой возник конфликт убрав ограничение целостности, отключив триггер, дав привилегии. Второй вариант: пропустить (не применять) транзакцию, в которой выполняется команда, приведшая к ошибке. Это делается командой ALTER SUBSCRIPTION имя  SKIP (lsn = LSN). Когда пропускается вся транзакция (чей LSN с COMMIT указывается в команде), то пропускаются все изменения сделанные транзакцией, в том числе не нарушающие никаких ограничений.

Если параметр подписки streaming=parallel, то LSN неудачных транзакций может записываться в лог кластера. В этом случае можно изменить значение на on или off и возобновить репликацию.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/logical-replication-conflicts.html 

Двунаправленная репликация

Двунаправленная репликация - два или более набора таблиц являются источниками изменений и приёмниками друг для друга. Направления репликации настраиваются независимо, но обычно настройки одинаковы. Для двух наборов таблиц создаётся две публикации и две подписки. Для трёх наборов - три и три.

При настройки двунаправленной репликации чем больше лаг, тем больше вероятность конфликтов. Чтобы избегать конфликтов используют горизонтальное или вертикальное «партиционирование». При горизонтальном на уровне приложения за каждым узлом закрепляют строки которые могут меняться или вставляться в таблицу. Например, в зависимости от значения в столбце таблицы. Например, две базы в двух городах. Сессии с базами меняют и вставляют строки относящиеся преимущественно к их городам. Ограничений со стороны базы данных нет и если приложение в одном городе перестанет работать, то клиенты могут быть направлены на приложение в другом городе и оно будет работать с любыми строками. При вертикальном «партиционировании», которое реже используется каждый узел может вносить изменения свой набор столбцов.

Цель двунаправленной репликации не увеличение производительности, а отказоустойчивость.

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

При настойке двунаправленной репликации необходимо на всех подписчиках указывать опцию origin=NONE.

Локальные команды (в локальных сессиях) имеют origin= NONE. Установка значения NONE означает, что подписке публикация будет пересылать изменения, которые не имеют origin, то есть внесённые локальными транзакциями, а не logical replication worker. Это позволяет избегать зацикливания в двунаправленной репликации.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/replication-origins.html 


Расширения

Расширение pgq

Расширение pgq присутствует только в Tantor «SE».

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

pgq позволяет разным компонентам системы взаимодействовать друг с другом асинхронно через «сообщения», которые помещаются в очередь и затем обрабатываются в более удобное для приложения-потребителя время.

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

pgq - низкоуровневое расширение и для многих сценариев может потребоваться создание программного кода для поддержки логики приложения.

Особенности:


Раздел 9. Платформа «Tantor»  

Обзор

Введение

Сценарии использования

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

Классический сценарий

Представьте, что у вас есть система мониторинга, которая зарегистрировала резкий спад производительности вашей базы данных. Первым делом, вы смотрите на показатели CPU, RAM и дисковой подсистемы, чтобы понять, где собственно проблема. Вы определяете, что «бутылочное горлышко» связано с процессором.

Затем, вы подключаетесь к серверу базы данных через SSH. Открыв терминал, вы запускаете, как правило, клиент psql и переходите к анализу системных представлений, например, pg_stat_statements, чтобы определить, какие запросы наиболее затратны.

После анализа системных представлений, вы просматриваете логи базы данных, в поисках планов запросов, которые создаются с использованием расширения auto_explain. Вы копируете интересующий вас план запроса и вставляете его в онлайн-визуализатор для дальнейшего анализа. Там вы определяете проблемные операции в запросе, такие как, например, Seq Scan вместо Index Scan.

В итоге, на основе собранной информации, вы принимаете решение об оптимизации: например, добавить индекс или переписать проблемный SQL-запрос.

Продвинутый сценарий с использованием платформы «Tantor»

С другой стороны, если у вас есть доступ к Платформе Tantor, всё становится ещё проще и быстрее. Вы открываете веб-браузер, переходите на Платформу и выбираете наблюдаемую базу данных. Там же вы быстро получаете список наиболее ресурсоемких запросов.

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

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

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

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

Инструменты мониторинга

В современном мире мониторинг производительности СУБД является критически важным компонентом для обеспечения надежности и эффективности любого приложения или сложной инфраструктуры.

PostgreSQL - одна из наиболее мощных и гибких СУБД, но её потенциал можно полностью раскрыть только с помощью правильных инструментов мониторинга.

Существует много универсальных систем мониторинга, таких как Zabbix, Grafana, OKMeter, New Relic, Munin, Cacti и Datadog. Они предоставляют широкий спектр функций для мониторинга различных аспектов инфраструктуры и приложений. Однако, именно из-за этой «универсальности» они часто не адаптированы для работы со специфическими особенностями и метриками PostgreSQL. Это означает, что они могут не предоставлять всю интересующую вас информацию в наиболее удобной форме, что может стать препятствием для оптимизации производительности.

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

Использование специализированного решения типа Платформа «Tantor» дает возможность сделать качественный скачок в настройке и мониторинге производительности PostgreSQL. С этим инструментом у вас будет возможность не только быстро определять узкие места и проблемы в вашей системе, но и проводить более точную настройку параметров СУБД для достижения максимальной эффективности.

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

Платформа «Tantor»

Платформа - это функциональное ПО с графическим пользовательским интерфейсом, установленное, как правило в периметре заказчика, создано оно для удобного администрирования кластеров PostgreSQL.

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

         Платформа «Tantor» необходима организациям, которые используют множество баз данных, каждая из которых обслуживает определенную информационную систему или сервис. Так как каждая система имеет свои особенности, различные типы нагрузки и данные - это делает базу данных сложным элементом корпоративной информационной системы. Следовательно, на сотрудниках лежит большая ответственность за нормальное функционирование СУБД, а «Платформа Tantor» упрощает их ежедневную работу.

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

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

https://docs.tantorlabs.ru/tp/4.0/index.html

Настройки пользователей

На Платформе «Tantor» управление пользователями и группами организовано через модуль администрирования, который позволяет выполнять различные операции. Основные функции включают добавление, активацию, деактивацию и удаление пользователей. Также доступны опции для управления правами пользователя, включая передачу прав администратора. Дополнительно, можно управлять группами пользователей, добавляя новые группы и управляя их членством, а также интегрировать систему с Active Directory для более глубокой интеграции с корпоративными учетными записями.

https://docs.tantorlabs.ru/tp/4.0/admin_users.html


Возможности мониторинга

Рабочие пространства

Рабочее пространство в Платформе Tantor - это веб-интерфейс, предназначенный для управления экземплярами сервера PostgreSQL. Это позволяет пользователям организовывать и управлять различными экземплярами баз данных, которые находятся в одном или нескольких рабочих пространствах.

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

https://docs.tantorlabs.ru/tp/4.0/glossary.html

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

Основное преимущество использования рабочих пространств на Платформе «Tantor» заключается в возможности централизованного мониторинга и управления всеми кластерами баз данных PostgreSQL предприятия. Это позволяет обеспечить единое управление всеми ресурсами баз данных, что критически важно для крупных организаций, стремящихся к оптимизации и повышению эффективности своих IT-операций.

Централизованное управление упрощает процессы настройки, мониторинга и обслуживания различных экземпляров PostgreSQL, обеспечивая:

  1. Быстрый доступ ко всей необходимой информации о состоянии каждого экземпляра и кластера.
  2. Проактивное управление и мониторинг, позволяющее своевременно реагировать на возможные проблемы или изменения в работе баз данных.
  3. Упрощение процессов масштабирования и добавления новых экземпляров и кластеров без необходимости значительной перенастройки системы.

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

Обзор экземпляра

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

На странице Экземпляра открывается меню с модулями для управления и мониторинга экземпляра базы данных. Меню включает следующие модули:

Overview: Общие сведения и показатели работы экземпляра.

Configuration: Настройки экземпляра.

Maintenance: Инструменты обслуживания.

DB Inspector: Инструменты для анализа структуры баз данных.

Query Profiler: Профилировщик для анализа запросов.

Current Activity: Отображение текущей активности.

Replication: Управление настройками репликации.

Tablespaces: Управление табличными пространствами.

Charts: Графики мониторинга.

Monitoring Config: Настройки системы мониторинга.

Advanced Analytics: Инструменты для продвинутого анализа данных.

Tasks: Планировщик для запуска отложенных задач на экземплярах СУБД.

https://docs.tantorlabs.ru/tp/4.0/instances/overview.html


Кластеры Patroni

Работа с кластерами Patroni на Платформе «Tantor» охватывает различные аспекты управления и мониторинга. Вкладка «Clusters» позволяет видеть все кластеры в рабочем пространстве, их статус, версию Patroni, а также ресурсы, такие как CPU и память. Можно переходить к подробной информации о каждом кластере, мониторить кластеры, настраивать их, а также управлять обслуживанием. Для каждого кластера доступны функции, такие как просмотр, мониторинг, пауза/обслуживание и настройка. Информация о кластерах включает данные о каждом экземпляре, их роли и статусы.


https://docs.tantorlabs.ru/tp/4.0/ug_clusters_pages.html

Профилировщик запросов

Профайлер запросов (Query Profiler) на Платформе «Tantor» использует расширение pg_stat_statements для сбора статистики по запросам PostgreSQL. Основная функция этого инструмента - идентификация и анализ медленных запросов. Профайлер позволяет выбирать различные временные интервалы для отображения данных, предлагает детальные метрики такие как время выполнения запроса, количество вызовов, время CPU и IO. Он также включает визуализации, такие как графики, и предоставляет возможность просмотра деталей запроса, включая текст и план выполнения.

Профайлер запросов на Платформе «Tantor» позволяет пользователям глубоко анализировать производительность SQL-запросов. Это помогает в оптимизации запросов путем предоставления данных о времени выполнения, использовании памяти, а также количестве и типах операций ввода-вывода. Используя эту информацию, разработчики и администраторы баз данных могут выявлять и устранять неэффективные запросы, что приводит к улучшению общей производительности системы.

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

https://docs.tantorlabs.ru/tp/4.0/instances/query_profiler.html 


Репликация

Модуль «Репликация» на Платформе «Tantor» предоставляет подробный мониторинг репликации PostgreSQL. Он включает две основные вкладки: «STANDBY'S» для управления репликами и «SLOTS» для управления слотами репликации. На вкладке «STANDBY'S» пользователи могут видеть список реплик с их статусами и доступом к детальной информации о каждой реплике. Вкладка «SLOTS» отображает список слотов репликации с их активностью и статусом. Эти инструменты помогают оптимизировать процесс репликации и обеспечивают надежную синхронизацию данных.

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

https://docs.tantorlabs.ru/tp/4.0/instances/replication.html 

Табличные пространства

Модуль «Табличные пространства» создан для эффективного контроля за использованием места табличными пространствами в базе данных. Он осуществляет сопоставление размера диска с размером каждого табличного пространства, что обеспечивает более детальное представление об объеме занимаемого пространства каждой части базы данных.

https://docs.tantorlabs.ru/tp/4.0/instances/tablespaces.html


Оповещения

Модуль «Оповещения» разработан для создания уведомлений о критических ситуациях в базе данных. Он обеспечивает возможность мониторинга изменений статуса оповещений, позволяя оперативно реагировать на важные события в базе данных. Этот инструмент обеспечивает эффективное уведомление о возможных проблемах, что позволяет быстро и точно реагировать на изменения в работе базы данных.

https://docs.tantorlabs.ru/tp/4.0/ug_alerts.html


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

На Платформе «Tantor» модуль конфигурации мониторинга позволяет настроить слежение за базами данных, управлять триггерами оповещений и настраивать условия для оповещений на основе собранных метрик PostgreSQL. Это включает выбор баз данных для мониторинга, установку триггеров для предупреждений, проблем и восстановления, а также сохранение изменений для активации настроенных параметров мониторинга. Инструмент предоставляет возможность детально настроить параметры мониторинга для эффективного управления производительностью и безопасностью баз данных.

https://docs.tantorlabs.ru/tp/4.0/instances/monitoring_config.html 


Аналитика

Расширенная аналитика на Платформе «Tantor» позволяет детально анализировать работу серверов баз данных. Она охватывает анализ медленных запросов, блокировок, ошибок, системных действий и логов. Включает разделы для мегазапросов и диагностики проблем с запросами, позволяя пользователям отслеживать производительность и находить узкие места. Интерфейс предлагает графики и сводки по хостам, обеспечивая удобство мониторинга и аналитики в режиме реального времени.

https://docs.tantorlabs.ru/tp/4.0/instances/pg_monitor/pg_monitor.html


Возможности управления

Активности фоновых процессов

Модуль «Текущая активность» на Платформе «Tantor» отображает детальную информацию о пользовательских и системных процессах баз данных в реальном времени. Это включает мониторинг активных, ожидающих и блокирующих сессий. Для каждого процесса показываются такие параметры, как использование CPU, памяти, скорость чтения/записи, и состояние процесса. Функция «TERMINATE» позволяет завершить процессы напрямую через интерфейс. Все данные обновляются каждые пять секунд и могут быть «заморожены» для удобства анализа.

Модуль «Текущая активность» также предлагает удобные фильтры для сортировки и поиска процессов по различным параметрам, таким как имя пользователя, база данных или состояние сессии. Это делает его мощным инструментом для быстрого выявления и решения проблем в базах данных, особенно в высоконагруженных средах, где немедленное вмешательство может предотвратить длительные простои или сбои системы.

https://docs.tantorlabs.ru/tp/4.0/instances/activity.html 

 Настройки

Модуль «Настройки» на Платформе «Tantor» предоставляет удобный интерфейс для просмотра и изменения файла конфигурации postgresql.conf, а также конфигурацию кластерного программного обеспечения Patroni. Он автоматически рекомендует оптимальные значения для различных параметров, позволяет применить эти значения и требует перезагрузку или перезапуск экземпляра для вступления изменений в силу. Интерфейс также предоставляет цветовую кодировку для легкой идентификации статуса параметров: по умолчанию, измененные и требующие перезагрузки или перезапуска. Пользователи могут фильтровать параметры по статусу и категории для удобства управления.

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

https://docs.tantorlabs.ru/tp/4.0/instances/instance_configuration.html 


Анализ схемы данных

Модуль «Инспектор Баз Данных» на Платформе «Tantor» позволяет проводить анализ схемы данных базы PostgreSQL. Используя HEALTHCHECKS, можно определить потенциальные проблемы, такие как неиспользуемые или избыточные индексы, таблицы с большим размером или неоптимальными настройками. Пользователю доступны детали каждой проблемы, с возможностью применения рекомендуемых изменений прямо через интерфейс. Этот инструмент помогает улучшить производительность базы данных и обеспечить её корректную конфигурацию.

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

https://docs.tantorlabs.ru/tp/4.0/instances/DB_inspector.html 


Регламентное обслуживание

В модуле «Обслуживание» Платформы «Tantor» можно управлять задачами по поддержанию баз данных PostgreSQL, такими как исправление раздутия таблиц и индексов, а также устранение переполнения счетчика транзакций. Пользователи могут выбирать конкретные действия для исправления проблем и запускать команды VACUUM, REINDEX, или ANALYZE для оптимизации производительности базы данных. История обслуживания предоставляет доступ к подробностям и результатам прошлых операций.

На странице «Обслуживание» можно также настроить автоматические регламентные задачи для повышения эффективности операций обслуживания. Это включает возможность планирования задач на регулярной основе, что помогает поддерживать базу данных в оптимальном состоянии без необходимости постоянного вмешательства администратора.

https://docs.tantorlabs.ru/tp/4.0/instances/maintenance.html


Планировщик задач

Модуль «Задачи» на Платформе позволяет пользователям автоматизировать и планировать выполнение различных операций. С его помощью можно настроить запуск действий по заданному расписанию, что включает выполнение системных команд или SQL-скриптов. Эта функциональность идеально подходит для автоматизации рутинных задач управления базами данных, таких как обновления, резервное копирование, или процедуры очистки, обеспечивая повышение эффективности и снижение вероятности ошибок за счет автоматизации процессов.

https://docs.tantorlabs.ru/tp/4.0/admin_scheduler.html


Раздел 10. Дополнительные возможности и изменения СУБД Tantor

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

Улучшения в ядре СУБД «Tantor»

Оптимизация алгоритма сжатия данных pglz

Во всех версиях всех СУБД «Tantor» оптимизирован алгоритм сжатия данных pglz. Оптимизация удаляет потенциально избыточные операции, повышая скорость сжатия в 1.4 раза.

Алгоритм сжатия pglz применяется по умолчанию.

postgres=# \dconfig *compress*

    Список параметров конфигурации

         Параметр          | Значение

---------------------------+----------

 default_toast_compression | pglz

 libpq_compression         | off

 wal_compression           | off

(3 строки)

Сжатие используется только для типов данных переменной ширины (например, integer фиксированной длины и не сжимается, text переменной и сжимается) и используется только тогда, когда режим хранения столбца MAIN или EXTENDED. EXTENDED является значением по умолчанию для большинства типов данных, поддерживающих хранение, отличное от PLAIN. Режим хранения можно  установить командой:

ALTER TABLE имя ALTER COLUMN столбец SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN };

Алгоритм сжатия можно поменять на уровне столбца:

ALTER TABLE имя ALTER COLUMN столбец SET COMPRESSION {DEFAULT | pglz | lz4};

Технические детали оптимизаций кода алгоритма pglz в СУБД «Tantor»:

1) Используется более компактная хэш-таблица с индексами типа uint16  вместо указателей

2) Игнорируется prev-указатель в хэш-таблице

3) Используются более эффективные 4-байные операции сравнения вместо 1-байтных.

Также макрофункции заменены обычными функциями (не влияет на производительность).

 Оптимизация для увеличения производительности при работе с 1С

Для использования с программными продуктами 1C выпускается сборка СУБД «Tantor SE 1C», которая включает расширения:

1) fasttrun: создаёт функцию fasttruncate(&lsquo;имя_таблицы') для использования вместо команды TRUNCATE. При использовании этой функции не вносятся изменения (не порождается версия строки) в таблицы системного каталога (pg_class).

2) fulleq: создаёт оператор ==, который возвращает true, когда операнды равны или оба имеют значение NULL

3) mchar: поддержка типов данных mchar и mvarchar имеющихся в Microsoft SQL Server и использующихся в 1С. Поддержка включает в себя набор операторов, функций и использования библиотек ICU для независимого от платформы сравнения и сортировки значений.

4) online_analyze: выполняет сбор статистики для оптимизатора (эквивалент команды ANALYZE) после выполнения команд INSERT, UPDATE, DELETE, SELECT INTO в том числе по временным таблицам (последнее существенно для 1С). Имеет набор параметров которыми можно настраивать когда будет вызываться сбор статистики.

Также имеются улучшения:

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

2) Оптимизация разбора запросов с операторами LIKE и поддержка этого оператора для типов данных, использующихся в 1С.

3) Изменения в логике планировщика для создания оптимальных планов запросов, типичных для 1С.

https://docs.tantorlabs.ru/tdb/ru/15_6/se1c/online_analyze.html 


Расширения в составе СУБД «Tantor»

C PostgreSQL поставляются стандартные расширения. Все они присутствуют в СУБД «Tantor» соответствующих сборок.

Помимо них вместе с программным обеспечением СУБД «Tantor»  поставляются дополнительные расширения и приложения.

Большая часть расширений не требуют отдельной установки (deb или rpm), находятся в едином пакете дистрибутива СУБД «Tantor» и могут использоваться так же, как используются стандартные расширения PostgreSQL.

Также имеются расширения и утилиты (приложения), которые распространяются отдельно в виде пакета или архива. Такие расширения и приложения могут скачиваться из репозитариев Тантор Лабс.

На слайде жирным отмечены расширения, которые ранее мы не рассматривали и раскроем их сейчас.

fasttrun (расширение для 1С)

Расширение содержит функцию fasttruncate, предназначенную для эффективного усечения (TRUNCATE) временных таблиц без внесения изменений в таблицы системного каталога (pg_class). Это решение важно для предотвращения проблем с производительностью, связанных с увеличением размера каталога при частом использовании временных таблиц. Временные таблицы массово используются в приложениях «1С:Предприятие».

fulleq (расширение для 1С)

Модуль fulleq - также доступен только в версии «1С».

В стандартной версии PostgreSQL оператор "=" используется для сравнения значений, и если хотя бы один из операндов имеет значение NULL, результатом сравнения будет NULL. Однако в различных системах управления базами данных, включая СУБД 1С, для работы со значениями NULL используется оператор "==".

Команда fulleq решает эту проблему, предоставляя оператор "==", который возвращает true, когда операнды равны или оба имеют значение NULL.

Эта команда полезна для работы с базами данных, особенно для поддержки 1С, где операторы и семантика работы с NULL отличаются от стандарта PostgreSQL. Она позволяет корректно обрабатывать значения NULL и сравнивать их с другими значениями, что облегчает работу с базами данных, использующими 1С.

Для использования команды необходимо установить соответствующий модуль в PostgreSQL.

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

Оператор "==", примененный к двум операндам, возвращает true, если они равны или оба имеют значение NULL.

Оператор "==", примененный к двум операндам, возвращает false, если они не равны или один из них имеет значение NULL.

Использование команды fulleq в приведенном примере:

1. Создается таблица "table1" с двумя столбцами "id" и "name".

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

3. Выполняется запрос "SELECT id, name FROM table1 WHERE id == name;", который возвращает строки, где значения столбцов "id" и "name" равны.

mchar (расширение для 1С)

Расширение mchar, доступно в версии СУБД tantor SE1С:

Предоставляет дополнительные типы данных для совместимости с Microsoft SQL server (MS SQL).

Добавляет поддержку типов mchar mvarchar для совместимостим с ms sql.

Для типов  mchar, mvarchar поддерживаются функции и операторы:

length()

substr(str, pos[, length])

|| конкатенация с разными типами (mchar || mvarchar)

< <= = >= > сравнение без чувствительности к регистру (ICU)

&< &<= &= &>= &> сравнение с чувствительностью к регистру (ICU)

LIKE

SIMILAR TO

~ (регулярные выражения)

Неявное приведение типов mchar к mvarchar и обратно

Индексы типов b-tree и hash index

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

https://docs.tantorlabs.ru/tdb/ru/15_6/se1c/mchar.html 

orafce

Модуль orafce реализован в Tantor «SE».

Orafce содержит некоторые полезные функции, которые могут помочь при переносе приложений с Oracle на PostgreSQL или которые могут быть полезны в общем.

Функции и операторы расширения Orafce эмулируют подмножество функций и пакетов из Oracle RDBMS.

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

Эти функции позволяют упростить миграцию на Tantor и снизить затраты на перенастройку приложений.

Подробнее про расширение:

При миграции с СУБД Oracle Database на СУБД «Tantor» в командах и программном коде могут использоваться функции, процедуры, типы данных функционал, который имеются только в Oracle Database и отсутствуют в постгрес. Переписывать код может быть достаточно трудоёмко, особенно если команд много.

Расширение orafce создаёт большое количество функций, которые работают так же, как одноимённые функции и процедуры в Oracle Database.

Это наиболее распространённые подпрограммы, которые чаще всего используются в коде приложений, работающих с Oracle Database. Расширение не покрывает весь набор функций, также синтаксис вызова некоторых функций может отличаться и не нужно предполагать, что команды, SQL которые выполнялись в Oracle Database будут выполняться в постгрес.

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

Также функции из этого расширения могут быть полезными и сами по себе.

В Oracle Database программные единицы (функции и процедуры) находятся в «пакетах».

В постгрес есть объект «схема», который обладает схожим функционалом, поэтому расширение создаёт довольно большое количество схем, имена которых соответствуют названиям пакетов в Oracle Database.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/orafce.html

pgsql-http

Модуль pgsql-http - доступен только в Special Edition.

Модуль дает возможность написать триггер, вызывающий веб-сервис, способный вернуть результат, либо заставить этот сервис обновляться в соответствии с новым состоянием базы данных. Иными словами расширение pgsql-http предоставляет возможность выполнять HTTP и HTTPS запросы прямо из SQL.

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

pgsql-http может быть полезен в ряде задач:

Интеграция с внешними API - в некоторых случаях удобнее работать с внешними REST API напрямую из PostgreSQL, особенно когда эти данные требуется включить в SQL запросы. Pgsql-http позволяет делать это, поддерживая все основные методы HTTP, включая GET, POST, PUT, DELETE и PATCH.

Web-скрэйпинг - Pgsql-http может быть использован для извлечения данных с веб-страниц напрямую в PostgreSQL, что может быть полезно для аналитики и других задач.

Интерактивные приложения: В некоторых сценариях использования PostgreSQL может быть частью интерактивного веб-приложения, где база данных взаимодействует с пользователем посредством HTTP. Pgsql-http может использоваться для отправки запросов на сервер приложений и получения ответов на них.

Данные в реальном времени - в некоторых случаях, может понадобиться доступ к данным, которые постоянно обновляются и доступны через HTTP API. С помощью pgsql-http, можно запросить эти данные напрямую из PostgreSQL.

pg_store_plans

Во всех версиях СУБД «Tantor», доступен доработанный Тантор Лабс модуль - pg_store_plans:

Модуль предоставляет средства для отслеживания статистики плана выполнения всех операторов SQL, выполняемых СУБД Tantor.

Используется платформой Tantor для сбора статистики планов запросов.

В отличие от других инструментов, таких как auto_explain, pg_stat_statements или pg_stat_plans - pg_store_plans способен собирать и хранить полные планы запросов, а не только статистику или текст запросов.

Это позволяет вам анализировать, как конкретные запросы выполняются в системе, и оптимизировать их на основе этой информации.

Использование pg_store_plans может увеличить нагрузку на вашу систему из-за дополнительного сбора и хранения информации о планах запросов.

Поэтому перед его использованием следует тщательно оценить требования к производительности.

Основные особенности pg_store_plans:

Сбор планов запросов: pg_store_plans автоматически сохраняет планы выполнения запросов, что позволяет исследовать, как запросы выполняются в вашей базе данных.

Длительное хранение: pg_store_plans хранит планы запросов на протяжении длительного времени, что позволяет вам анализировать исторические данные и определять, как изменения в вашем приложении или базе данных влияют на производительность запросов.

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

Совместимость с другими расширениями: pg_store_plans может быть использован в сочетании с другими расширениями PostgreSQL для более глубокого анализа производительности, такими как pg_stat_statements или pg_qualstats.

pg_variables

В версии SE добавлен Модуль pg_variables.

Расширение pg_variables позволяет определять и использовать переменные внутри запросов SQL на сервере PostgreSQL.

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

Предоставляет средства для отслеживания статистики плана выполнения для всех SQL-запросов, выполненных сервером Tantor.

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

По умолчанию созданные переменные не являются транзакционными (т.е. на них не влияет операторами `BEGIN`, `COMMIT` или `ROLLBACK`).

Еще немного о расширении в целом.

Расширение позволяет хранить в памяти серверного процесса значения переменных различных типов, в том числе численных, текстовых, датавременных, логического, jsonb, массивов, составных типов. Переменные доступны в рамках сессии.

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

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

Функционал аналогичен переменным пакетов и контекстов приложений (application contexts) в Oracle Database, поэтому расширение может использоваться при миграции приложений на СУБД Тантор.

https://docs.tantorlabs.ru/tdb/ru/15_6/se/pg_variables.html 

pg_wait_sampling

Модуль pg_wait_sampling - доступен во всех версиях СУБД Tantor.

PostgreSQL использует многопроцессную архитектуру, и процессы часто ждут каких-либо событий, таких как блокировки, IO операции или внутренние процессы PostgreSQL.

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

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

Ключевые функции и способы применения pg_wait_sampling:

Сбор статистики ожидания - pg_wait_sampling собирает статистику о том, какие процессы ждут и чего они ждут. Это может помочь определить, какие операции вызывают задержки.

Анализ производительности - используя информацию, собранную pg_wait_sampling, можно определить проблемные области в производительности и найти способы улучшения.

Диагностика блокировок - pg_wait_sampling может помочь в диагностике и решении проблем с блокировками, показывая, какие процессы ожидают освобождения блокировок.

Интеграция с другими инструментами - pg_wait_sampling может быть интегрирован с другими инструментами мониторинга и производительности для более глубокого анализа.

 pg_background

Расширение pg_background представлено в версиях Tantor SE и Tantor BE.

Расширение позволяет пользователю выполнять произвольную команду в фоновом режиме и реализовать:

Этот модуль поставляется со следующими SQL API:

pg_background_launch - принимает SQL-команду, которую пользователь хочет выполнить, и размер буфера очереди. Эта функция возвращает идентификатор процесса фонового рабочего.

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

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


Дополнительно поставляемые программы

pg_anon

Во всех версиях СУБД «Tantor» доступен pg_anon. 

pg_anon - это автономная программа, написанная на Python, предназначенная для работы с PostgreSQL (начиная с версии 9.6 и выше), которая выполняет следующие задачи:

WAL-G

WAL-G (Write-Ahead Log Guard) - это инструмент для создания зашифрованных, сжатых резервных копии? Tantor (полных и инкрементальных) и их отправки, получения «из» и «в» хранилища без сохранения на фаи?ловои? системе. Он разработан для использования с WAL архивами (Write-Ahead Logs), которые являются журналом транзакций и записывают все изменения, сделанные в базе данных.

WAL-G предоставляет несколько полезных функций:

Резервное копирование. WAL-G позволяет регулярно создавать резервные копии базы данных PostgreSQL, сохраняя WAL архивы встроенными в PostgreSQL средствами. Это позволяет восстановить данные до конкретного момента времени.

Восстановление. WAL-G позволяет восстанавливать базу данных PostgreSQL из резервных копий и WAL архивов. Он предоставляет удобный интерфейс для выбора конкретной точки восстановления по времени или с помощью LSN (Log Sequence Number).

Управление хранилищем. WAL-G может управлять хранилищем резервных копий и WAL архивов. Он поддерживает оптимизацию пространства и удаление устаревших файлов.

Управление версиями. WAL-G поддерживает возможность сохранять несколько версий резервных копий для восстановления из разных моментов времени.

Шифрование. WAL-G поддерживает шифрование резервных копий и WAL архивов для обеспечения безопасности данных.

В целом, WAL-G облегчает процесс резервного копирования и восстановления данных в PostgreSQL, предоставляя полный контроль над WAL архивами и удобный интерфейс для управления ими.

 pg_configurator

И наконец, программа pg_configurator, таже доступна во всех версиях.

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

pg_configurator предлагает рекомендуемые параметры сервера PostgreSQL на основе анализа аппаратных ресурсов, таких как доступная память, количество процессоров и дисковое пространство и т.д Это позволяет оптимально использовать имеющиеся ресурсы и увеличить производительность сервера.

tantorlabs.ru

страница  из