Задачи администрирования
Управление расширениями
13
Авторские права
© Postgres Professional, 2016–2022.
Авторы: Егор Рогов, Павел Лузанов, Илья Баштанов
Использование материалов курса
Некоммерческое использование материалов курса (презентации,
демонстрации) разрешается без ограничений. Коммерческое
использование возможно только с письменного разрешения компании
Postgres Professional. Запрещается внесение изменений в материалы
курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу:
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за
любые повреждения и убытки, включая потерю дохода, нанесенные
прямым или непрямым, специальным или случайным использованием
материалов курса. Компания Postgres Professional не предоставляет
каких-либо гарантий на материалы курса. Материалы курса
предоставляются на основе принципа «как есть» и компания Postgres
Professional не обязана предоставлять сопровождение, поддержку,
обновления, расширения и изменения.
2
Темы
Расширения в PostgreSQL
Создание и управление расширениями
Обновление расширений
Особенности работы pg_dump
3
Расширяемость PostgreSQL
Возможности
функции и языки программирования
типы данных, операторы, методы доступа
обертки сторонних данных (FDW)
Механизмы
изменяемый системный каталог
API для подключения внешних обработчиков
загрузка и выполнение пользовательского кода
Расширяемость — важнейшая черта PostgreSQLэто возможность
подключать «на лету» новый функционал без изменения кода сервера.
Таким образом можно добавлять языки программирования
и разрабатывать на них функции, определять новые типы данных
и операторы для работы с ними, создавать новые методы доступа для
типов данных, разрабатывать обертки сторонних данных для
подключения к внешним источникам.
Для того чтобы это было возможным, системный каталог PostgreSQL
хранит большое количество информации об объектах БД. Эта
информация не зашита жестко в код сервера. Пользователи могут
изменять содержимое таблиц системного каталога, тем самым
добавляя новые объекты и связанный с ними функционал.
Кроме того, в исходном коде PostgreSQL встроено большое количество
хуков и различных API для подключения пользовательских функций.
Это делает возможным разрабатывать такие расширения как
pg_stat_statements, auto_explain, pldebugger и многие, многие другие.
Завершает картину возможность загружать в серверные процессы
пользовательский код. Например, можно написать разделяемую
библиотеку и подключать ее по ходу работы.
В качестве предостережения следует отметить, что выполнение
процессами сервера неправильно написанного пользовательского кода
может привести к катастрофическим последствиям. Следует доверять
только проверенному коду из надежных источников.
4
Расширения в PostgreSQL
Упаковка связанных объектов БД
связь объектов с расширением, каскадное удаление
инструменты для перехода на новые версии
pg_dump
сохранение связи между объектами
Часто требуется добавить в базу данных связанные между собой
объекты. Например, для нового типа данных потребуются функции
и операторы.
Чтобы установить зависимости между отдельными объектами,
в PostgreSQL используется механизм расширений. Связанные объекты
упаковываются в единое расширение, что облегчает управление:
отдельный объект расширения нельзя удалить, а удаление
расширения автоматически удаляет все его объекты;
специальные инструменты облегчают переход на новые версии.
Копия базы данных, выполненная утилитой pg_dump, не может просто
выгружать описания отдельных объектов расширения, ведь при
восстановлении из такой копии принадлежность к расширению
потеряется. Поэтому утилита pg_dump сохраняет связь между
объектами и расширением.
5
Источники
Пакет дистрибутива и каталог contrib
дополнительно поставляемые модули
дополнительно поставляемые программы
PGXN — сеть расширений
Возможность создания собственного расширения
Несколько десятков расширений распространяются вместе с СУБД
и поддерживаются разработчиками PostgreSQL. Обычно они
устанавливаются из того же пакета, что и ядро. Исходный код таких
расширений находится в подкаталоге contrib.
Кроме расширений, в пакете (и в каталоге contrib) находятся несколько
дополнительных программ.
Еще один источник — PostgreSQL Extension Network (PGXN) — сеть
расширений, созданная по аналогии с сетью CPAN для Perl.
Расширения могут распространяться и другими способами, в том числе
через пакетные репозитории дистрибутивов ОС.
А можно разработать собственное расширение. Возможности и
свойства расширений будут рассмотрены в демонстрации на примере
учебного расширения uom.
7
Управление расширением
Команды управления расширениями
загрузка объектов в базу данных — CREATE EXTENSION
обновление версии — ALTER EXTENSION
удаление всех объектов расширения — DROP EXTENSION
Файлы расширений
управляющие файлы
файлы SQL
Для управления расширениями в PostgreSQL используются команды
SQL DDL.
Загрузка объектов расширения в базу данных выполняется при
создании расширения (CREATE EXTENSION). Переход на новую
версию, перемещение в другую схему — ALTER EXTENSION.
А удалить расширения со всеми его объектами можно командой
DROP EXTENSION. Не требуется разрабатывать отдельный uninstall-
скрипт.
Для работы этих команд в составе расширений должны быть
специальные файлы. К ним относятся управляющие файлы,
содержащие важную информацию о свойствах расширения, а также
файлы SQL с командами создания объектов расширения.
Как правило, расширения содержат и другие файлы, например,
разделяемые библиотеки с функциями для поддержки создаваемых
объектов. Но, с точки зрения управления расширениями, такие файлы
не важны.
8
Управляющие файлы
Имя файла: имя.control
Расположение: SHAREDIR/extension
# Некоторые параметры
directory = 'extension' # каталог для файлов SQL
default_version = 1.0 # версия по умолчанию
relocatable = true # возможность изменить схему
superuser = true # создает только суперпользователь
encoding = UTF8 # кодировка файлов SQL
#requires = '' должны быть установлены
comment = 'Use only ASCII characters'
pg_available_extensions
При выполнении команды CREATE EXTENSION механизм расширений
проверяет наличие управляющего файла в каталоге
SHAREDIR/extension.
Расположение SHAREDIR можно посмотреть командой
$ pg_config --sharedir
Имя управляющего файла состоит из имени расширения, к которому
добавляется «.control».
Управляющий файл имеет формат конфигурационных файлов
PostgreSQL и состоит из пар «ключ = значение». PostgreSQL не
определяет кодировку символов файла, поэтому следует использовать
только символы ASCII.
Список доступных расширений находится в таблице системного
каталога pg_available_extensions.
10
Создание расширения
CREATE EXTENSION имя [VERSION 'ве рси я'];
default_version = 1.0
...
\echo Use "CREATE EXTENSION имя" to load this file. \quit
COMMENT ON EXTENSION имя IS 'Описание на русском';
-- Создание объектов расширения
...
имя.control
имя--версия.sql
если версия
не указана
pg_available_extension_versions
Помимо управляющего файла, требуется еще файл SQL с командами
на создание объектов БД. Имя файла SQL зависит от устанавливаемой
версии расширения.
Версию расширения можно явно указать в предложении VERSION
команды CREATE EXTENSION. По умолчанию будет использоваться
версия из параметра default_version управляющего файла.
Имя файла SQL строится по шаблону имя--версия.sql,
где версия не обязательно должна состоять из цифр. Она может
включать и другие символы (кроме «--» , а также «-» в начале или
в конце).
Список доступных версий расширений находится в таблице системного
каталога pg_available_extension_versions.
Строки файла SQL, начинающиеся на \echo, механизм расширений
считает комментариями. Для предотвращения случайного запуска
файла из psql, обычно в начало файла SQL добавляют такую строку
с предупреждением и завершают ее командой \quit.
В файле SQL можно использовать кириллицу, предварительно указав
кодировку символов в параметре encoding управляющего файла.
Например, можно задать русскоязычный комментарий к расширению
в команде COMMENT ON EXTENSION.
12
Выбор схемы
CREATE EXTENSION имя [SCHEMA схема];
relocatable = false
schema = схема
...
SET LOCAL search_path TO @extschema@ ;
... SELECT @extschema@ .function_name()...
имя.control
имя--версия.sql
макроподстановка
Расширение как объект базы данных относится к определенной схеме.
Обычно все объекты расширения размещают в этой же схеме, это
позволяет расширению иметь отдельное пространство имен для
объектов.
Схему расширения можно явно указать в команде CREATE EXTENSION
или задать в параметре schema управляющего файла. Если ни одно из
этих значений не задано, действует общее правило: используется
первая доступная схема из параметра конфигурации search_path.
Выбранная в результате схема явно задается в search_path в начале
выполнения файла SQL. Внутри самого файла можно обращаться
к схеме расширения, используя макроподстановку @extschema@.
Если параметр расширения relocatable установить в true (по умолчанию
false), то расширение вместе с его объектами можно будет переносить
в другую схему командой:
ALTER EXTENSION имя SET SCHEMA новая_схема;
14
Обновление: 1.0 → 1.1
1. CREATE EXTENSION имя;
\echo Use "CREATE EXTENSION имя" to load this file. \quit
-- Создание всех объектов версии 1.1
имя--1.1.sql
\echo Use "ALTER EXTENSION имя" to load this file. \quit
-- Команды обновления из версии 1.0 в 1.1
имя--1.0--1.1.sql
2. ALTER EXTENSION имя UPDATE;
default_version = 1.1
...
имя.control
Если со временем потребуется изменить существующие объекты
расширения или добавить новые, выпускается следующая версия.
В управляющем файле новой версии расширения обычно меняется
параметр default_version. А при установке возможны две ситуации:
1. Предыдущая версия расширения не установлена.
Следует подготовить файл SQL для новой версии, включающий
создание всех объектов расширения.
2. Установлена одна из предыдущих версий расширения.
Следует подготовить файл SQL для обновления версии. Формат
имени файла обновления следующий:
имя--старая_версия--новая_версия.sql.
Внутри такого файла должны быть только команды, обновляющие
объекты расширения со старой версии на новую.
Само обновление выполняется командой:
ALTER EXTENSION имя UPDATE;
15
Обновление: 1.0 → 1.2
ALTER EXTENSION имя UPDATE TO '1.2';
\echo Use "ALTER EXTENSION имя" to load this file. \quit
-- Команды обновления из версии 1.0 в 1.1
имя--1.0--1.1.sql
текущая версия 1.0
pg_extension_update_paths ('имя')
\echo Use "ALTER EXTENSION имя" to load this file. \quit
-- Команды обновления из версии 1.1 в 1.2
имя--1.1--1.2.sql
При наличии нескольких версий расширения, в команде ALTER
EXTENSION … UPDATE можно явно указать требуемый номер версии.
Команда ALTER EXTENSION умеет последовательно выполнять
несколько файлов обновления для перехода с текущей на
запрошенную версию. Например для перехода с версии 1.0 на версию
1.2 сначала будут выполнен файл имя--1.0--1.1.sql, а затем
имя--1.1--1.2.sql.
Механизм расширений ничего не знает о том, какая версия новее,
и строит возможные цепочки обновлений исходя из имеющихся
файлов. Это позволит при наличии файла имя--1.2--1.0.sql
перейти с версии 1.2 на 1.0. Если есть несколько путей обновления
до запрошенной версии, то выбирается наиболее короткий.
Функция pg_extension_update_paths('имя') показывает возможные пути
обновления для указанного расширения.
16
Управляющие файлы
Дополнительные файлы: имя--версия.control
Расположение: SHAREDIR/extension
...
#requires = '' должны быть установлены
имя.control
...
requires = 'postgres_fdw'
имя--1.1.control
Помимо основного управляющего файла, в составе расширения могут
быть еще и дополнительные файлы для отдельных версий.
Формат имени таких файлов: имя--версия.control.
При создании расширения считывается основной управляющий файл
и дополнительный файл этой версии (если он есть). Параметры
дополнительного файла имеют предпочтение перед основным.
В приведенном примере при установке версии расширения 1.1 будет
проверяться наличие установленного расширения postgres_fdw, хотя
в предыдущей версии этого не требовалось.
18
CREATE FUNCTION ...
CREATE VIEW ...
CREATE TABLE ...
pg_dump: команды DDL
CREATE EXTENSION имя;
CREATE EXTENSION IF NOT EXISTS имя WITH SCHEMA схема;
имя--версия.sql
вывод утилиты pg_dump
Утилита pg_dump обрабатывает расширения особым образом.
Чтобы не потерять зависимости объектов от расширения, нельзя
просто выгружать команды определения отдельных объектов
(CREATE FUNCTION, CREATE VIEW,…). В копию включается только
команда CREATE EXTENSION, при выполнении которой создаются
объекты расширения.
При восстановлении из такой копии расширение будет создано заново
со всеми объектами и связями с помощью установленных в системе
скриптов. Поэтому перед восстановлением нужно убедиться, что
в системе установлена такая же версия расширения, что и при
создании копии.
19
CREATE TABLE tab ...
SELECT pg_extension_config_dump('tab'::regclass);
pg_dump: строки таблиц
CREATE EXTENSION имя;
CREATE EXTENSION IF NOT EXISTS имя WITH SCHEMA схема;
COPY tab (...) FROM stdin;
...
\.
имя--версия.sql
pg_extension
вывод утилиты pg_dump
В расширение можно включать и таблицы.
По умолчанию строки таблиц, входящих в расширение, считаются его
частью и не выгружаются утилитой pg_dump.
Если же таблица содержит пользовательские данные, требуется
включить ее строки в выгрузку pg_dump. Для этого в файле SQL
расширения нужно вызвать для каждой такой таблицы функцию
pg_extension_config_dump().
Функция имеет два параметра. Первый — это OID таблицы, второй
(необязательный) — фраза WHERE, которую pg_dump будет применять
к таблице при выгрузке.
Эта же функция используется и для последовательностей, которые
могут быть связаны с таблицей. В вывод pg_dump будет записываться
вызов функции setval, устанавливающий последнее полученное из
последовательности значение.
Функцию pg_extension_config_dump() можно вызывать только из
файлов SQL расширения.
21
pg_dump: привилегии
CREATE EXTENSION имя;
CREATE TABLE tab ...
GRANT ALL ON tab TO public;
имя--версия.sql
pg_init_privs
REVOKE ALL ON tab FROM public;
GRANT ALL ON tab TO admin;
psql
CREATE EXTENSION IF NOT EXISTS имя WITH SCHEMA схема;
REVOKE ALL ON tab FROM public;
GRANT ALL ON tab TO admin;
вывод утилиты pg_dump
Скрипты расширений могут включать команды GRANT и REVOKE для
управления привилегиями на объекты расширения.
Информация о выданных или отозванных расширениями привилегиях
сохраняется в системном каталоге pg_init_privs. Это позволяет pg_dump
сформировать «разницу» в виде набора команд GRANT и REVOKE,
которые после выполнения CREATE EXTENSION устанавливают права
доступа на объекты такими, какими они были на момент создания
копии.
В приведенном примере скрипт расширения выдает права на таблицу
псевдороли public. Затем, в процессе эксплуатации, права на эту
таблицу у public отнимаются и передаются роли admin. В копию
pg_dump должны попасть не только команда выдачи привилегий на
таблицу для роли admin, но отзыв привилегий у псевдороли public,
которые будут выданы в результате выполнения CREATE EXTENSION.
22
Итоги
Расширяемость — важнейшее свойство PostgreSQL
Расширения — упаковка связанных объектов БД
Механизм расширений содержит инструменты для
обновления версий, поддержки работы pg_dump
23
Практика
1. Установите расширение uom и убедитесь, что оно появилось
в списке доступных.
2. Создайте расширение uom, не указывая версию.
Какая версия создалась и какими скриптами?
3. Добавьте в справочник футы и дюймы.
4. Измените доступ к справочной таблице:
привилегия SELECT должна быть только у специально
созданной роли, а не у всех.
5. Проверьте, как pg_dump выгружает объекты расширения:
таблицу, тип, функции и операторы, содержимое таблицы,
права доступа.
1. Файлы расширения расположены в подкаталоге uom домашнего
каталога пользователя student. Процесс установки аналогичен тому, что
использовался в демонстрации.
3. При добавлении записей важно, чтобы у добавленных записей
значение столбца predefined было false.
Коэффициенты пересчета:
1 фут = 0,3048 м
1 дюйм = 0,0254 м