15 Занятие 15: Задачи администрирования / Управление расширениями
Эта страница извлечена из официального PDF в нативный Markdown. Текст слайдов, код и комментарии сохранены в порядке чтения; исходные PDF и HTML остаются эталоном макета. HTML source: dba2_15_admin_extensions.html Archive: DBA2-handouts-16.zip Страниц PDF: 19
Page 1: Задачи администрирования / Управление расширениями
Авторские права
© Postgres Professional, 2016–2025 Авторы: Егор Рогов, Павел Лузанов, Илья Баштанов, Игорь Гнатюк Фото: Олег Бартунов (монастырь Пху и пик Бхрикути, Непал)
Использование материалов курса
Некоммерческое использование материалов курса (презентации, демонстрации) разрешается без ограничений. Коммерческое использование возможно только с письменного разрешения компании Postgres Professional. Запрещается внесение изменений в материалы курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу: edu@postgrespro.ru
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за любые повреждения и убытки, включая потерю дохода, нанесенные прямым или непрямым, специальным или случайным использованием материалов курса. Компания Postgres Professional не предоставляет каких-либо гарантий на материалы курса. Материалы курса предоставляются на основе принципа «как есть» и компания Postgres Professional не обязана предоставлять сопровождение, поддержку, обновления, расширения и изменения.
Page 2: Темы
- Расширения в PostgreSQL
- Создание расширений и управление ими
- Обновление расширений
- Особенности работы pg_dump
Page 3: Расширяемость PostgreSQL
Возможности
- функции и языки программирования
- типы данных, операторы, методы доступа
- обертки сторонних данных (FDW)
- Механизмы
- изменяемый системный каталог
- API для подключения внешних обработчиков
- загрузка и выполнение пользовательского кода
Комментарии преподавателя
Расширяемость — важнейшая черта PostgreSQL — это возможность подключать «на лету» новый функционал без изменения кода сервера.
Таким образом можно добавлять языки программирования и разрабатывать на них функции, определять новые типы данных и операторы для работы с ними, создавать новые методы доступа для типов данных, разрабатывать обертки сторонних данных для подключения к внешним источникам.
Для того чтобы это было возможным, системный каталог PostgreSQL хранит большое количество информации об объектах БД. Эта информация не зашита жестко в код сервера. Пользователи могут изменять содержимое таблиц системного каталога, тем самым добавляя новые объекты и связанный с ними функционал.
Кроме того, в исходном коде PostgreSQL встроено большое количество хуков и различных API для подключения пользовательских функций. Это дает возможность разрабатывать такие расширения как pg_stat_statements, auto_explain, pldebugger и многие, многие другие.
Завершает картину возможность загружать в серверные процессы пользовательский код. Например, можно написать разделяемую библиотеку и подключать ее по ходу работы.
https://postgrespro.ru/docs/postgresql/16/extend-how
В качестве предостережения следует отметить, что выполнение процессами сервера неправильно написанного пользовательского кода может привести к катастрофическим последствиям. Следует доверять только проверенному коду из надежных источников.
Page 4: Расширения
Группа взаимосвязанных объектов БД
- установка всех объектов одной командой
- невозможность удалить отдельный объект
- сохранение связи при выгрузке с помощью pg_dump
- инструменты для перехода на новую версию
- Источники
- в составе дистрибутива (contrib)
- внешние расширения
- возможность создания собственных расширений
Комментарии преподавателя
Бывают ситуации, когда несколько объектов базы данных логически связаны между собой. Например, несколько типов данных, функции и операторы для работы с ними, классы операторов. Такую связь можно сделать явной с помощью механизма расширений.
Это облегчает управление объектами:
● все объекты устанавливаются одной командой;
● невозможно удалить отдельный объект — расширение можно удалить только полностью;
● связь между объектами сохраняется и при создании резервной копии с помощью утилиты pg_dump;
● есть инструменты для управления версиями расширений.
В состав PostgreSQL входит значительное количество полезных расширений, частью из которых мы уже пользовались.
https://postgrespro.ru/docs/postgresql/16/contrib
https://postgrespro.ru/docs/postgresql/16/contrib-prog
Другой источник — PostgreSQL Extension Network (PGXN) — сеть расширений по аналогии с CPAN для Perl: https://pgxn.org/
Расширения могут распространяться и другими способами, в том числе через пакетные репозитории дистрибутивов ОС.
Page 5: Создание расширения
{#source-figure-005 caption=“Source slide page 5: Создание расширения”}
Комментарии преподавателя
Расширение устанавливается в базу данных командой CREATE EXTENSION. При этом должны существовать два файла:
● управляющий файл «имя.control» с параметрами расширения;
● скрипт создания объектов расширения «имя–версия.sql».
Версия традиционно имеет вид «1.0», «1.1» и т. д., но это не обязательно: она может состоять из любых символов (но не должна содержать «–» и начинаться или заканчиваться на «-»).
Обычно версию не указывают в команде CREATE EXTENSION, поскольку текущая актуальная версия записана в управляющем файле (параметр default_version) и используется по умолчанию.
Другие параметры в управляющем файле указывают на возможность перемещения объектов расширения между схемами (relocatable), зависимости от других расширений (requires), возможность установки только суперпользователем (superuser) и пр.
https://postgrespro.ru/docs/postgresql/16/extend-extensions
https://postgrespro.ru/docs/postgresql/16/sql-createextension
Расширение удаляется командой DROP EXTENSION. Скрипт для удаления объектов не требуется.
https://postgrespro.ru/docs/postgresql/16/sql-dropextension
Page 6: Установка расширения
Файлы с исходным кодом учебного расширения UOM (единицы измерения) расположены в каталоге uom домашнего каталога пользователя student:
Среди файлов есть управляющий файл с настройками:
default_version определяет версию по умолчанию, без этого параметра версию придется указывать явно; relocatable говорит о том, что расширение можно перемещать из схемы в схему (мы поговорим об этом чуть позже); encoding требуется, если используются символы, отличные от ASCII; comment определяет комментарий к расширению. Это не все возможные параметры; полный список можно узнать из документации. Файлы, общие для всех кластеров одной версии PostgreSQL, находятся в каталоге SHAREDIR:
В частности, файлы установленных расширений находятся в каталоге SHAREDIR/extension. Например, файлы расширения pg_buffercache:
Для установки расширений обычно используется утилита make. Если расширение требует компиляции, а PostgreSQL установлен из пакета, дополнительно нужно установить пакет для разработчиков; его имя обычно содержит слово dev, например postgresql-server-dev-16. Пакет включает все необходимое для сборки, в том числе заголовочные файлы PostgreSQL. Наше расширение содержит только функции на SQL и не требует компиляции и сборки, поэтому Makefile должен обеспечить только копирование файлов расширения в SHAREDIR/extension:
Переменная EXTENSION задает имя расширения; Переменная DATA определяет список файлов, которые надо скопировать в SHAREDIR (кроме управляющего); Последние строки не меняются, они подключают инфраструктуру PGXS для установки расширений. Важно, чтобы утилита pg_config была доступна — иначе неизвестны пути, по которым установлен PostgreSQL. Установим расширение, выполнив make install в каталоге расширения:
Page 7: Page 7
Установка расширения обычно выполняется суперпользователем, в окружении которого путь до исполняемых файлов PostgreSQL может быть не указан. В этом случае в команде установки нужно явно задать расположение утилиты pg_config:
Список расширений, установленных на сервере и доступных для загрузки в базы данных кластера, виден в системном каталоге:
В стандартных базах данных установлено только расширение plpgsql. Список версий нашего расширения:
Page 8: Page 8
Версии расширений в PostgreSQL понимаются как имена, а не как номера. Другими словами, 1.1 и 1.2 — это просто две разные версии, их порядок не определен. Загрузим в новую базу данных версию 1.0 расширения uom:
Расширение появилось в базе данных, оно содержит таблицу и функцию:
Объекты установлены в схему, в которой они были бы созданы по умолчанию; в данном случае — public. При создании расширения мы могли бы указать схему явно:
Функция умеет переводить значения из одной единицы длины в другую:
А в таблице хранится список поддерживаемых единиц измерения:
Объекты расширения были созданы SQL-скриптом для версии 1.0:
Page 9: Page 9
Первая строка файла предотвращает случайный запуск скрипта вручную, он должен работать только при выполнении CREATE EXTENSION. При создании расширения все команды выполняются в одной транзакции, поэтому команды управления транзакциями (и служебные команды, такие, как VACUUM) здесь не допускаются. Путь поиска (параметр search_path) будет установлен на единственную схему — ту, в которой создаются объекты расширения. Принадлежность к расширению не дает напрямую удалять объекты:
При этом механизм расширений не отслеживает изменения самих объектов. Например, добавление столбца в таблицу или изменение функции не вызовет ошибки. Вносить изменения в объекты расширения не следует. Расширение и его объекты можно переносить в другую схему (relocatable=true):
Вернем расширение в public:
Page 10: Обновление расширения
{#source-figure-010 caption=“Source slide page 10: Обновление расширения”}
Комментарии преподавателя
Обновление версии расширения выполняется командой ALTER EXTENSION UPDATE. При этом должен существовать скрипт обновления «имя–старая-версия–новая-версия.sql», содержащий необходимые для обновления команды.
Также необходимо изменить управляющий файл «имя.control», обновив актуальную версию и, возможно, другие параметры.
При необходимости может существовать и отдельный управляющий файл, привязанный к версии. Например, если в версии 1.2 появилась зависимость от другого расширения, то эту зависимость лучше указать не в основном управляющем файле, а в дополнительном файле версии 1.2. Параметры, указанные в дополнительном управляющем файле, имеют приоритет над параметрами основного.
В примере, приведенном на слайде, показаны скрипты обновления 1.0→1.1 и 1.1→1.2. Можно создать и скрипт 1.0→1.2, но, как правило, это не требуется: механизм расширений сам берет на себя выбор пути обновления с учетом доступных переходов между версиями. Например, если установлена версия 1.0, то ее можно обновить сразу до 1.2: сначала автоматически применится скрипт 1.0→1.1, а затем 1.1→1.2.
Как и при создании, при обновлении номер версии обычно не указывают — в этом случае обновление происходит до последней актуальной версии, записанной в основном управляющем файле.
https://postgrespro.ru/docs/postgresql/16/sql-alterextension
Page 11: Версии расширения и обновление
В следующей версии uom 1.1 добавлен тип данных для единиц длины, операторы сравнения для значений этого типа и класс операторов, позволяющий индексировать столбцы таблиц такого типа. Файл с изменениями:
При создании новой версии расширения возможны два сценария: В базе данных есть предыдущая версия, нужно обновить расширение. Предыдущей версии нет, нужно сразу создать более позднюю версию расширения. Убедимся, что мы можем перейти с версии 1.0 на версию 1.1. Список доступных вариантов обновления:
Выполним обновление:
Page 12: Page 12
Теперь будем создавать версию 1.1, предварительно удалив расширение. При удалении расширения удаляются и его объекты:
Сразу создаем расширение версии 1.1 в отдельной схеме, обеспечив видимость объектов в ней:
Для создания версии 1.1 механизм расширений сначала будет искать файл uom–1.1.sql, которого нет. Но к версии 1.1 можно прийти по цепочке: сначала создать версию 1.0, затем обновить до 1.1. Это самый короткий путь до версии 1.1, а в нашем примере и единственный. Посмотрим на тип данных uom. Для него определены операторы сравнения единиц длины:
Новый тип можно использовать в качестве типа данных для столбца таблицы:
Данные в таблице можно сортировать:
Page 13: Page 13
Можно построить индекс B-дерево:
И если запретить планировщику последовательный доступ, новый индекс будет использован при выполнении запроса:
Утилита pg\_dump
Утилита pg_dump выгружает только команду CREATE EXTENSION, но не команды создания объектов расширения. Поэтому для восстановления из резервной копии нужно, чтобы на сервере были установлены все используемые расширения. В следующей версии расширения 1.2 в таблицу добавлен столбец predefined. Он нужен для определения строк, которые были вставлены в таблицу не скриптом расширения, а уже после его создания. Файл обновления:
Скрипт вызывает функцию pg_extension_config_dump, чтобы утилита выгружала строки таблицы, удовлетворяющие условию. Для перехода на версию 1.2 мы не можем просто удалить расширение и пересоздать его. Помешает столбец len таблицы t:
Если мы не готовы удалять таблицу (или столбец len), то следует выполнить обновление:
Без указания версии обновление выполняется до версии по умолчанию из управляющего файла:
Page 14: Page 14
Теперь в логическую копию будут попадать, кроме CREATE EXTENSION, и данные таблицы uom_ref. Если выгружать базу данных целиком, то в резервную копию попадают все установленные расширения и такое поведение обычно нас устраивает. Однако если при выгрузке указать схему, то установленные в ней расширения в копию не попадут:
Восстановить содержимое таблицы uom_ref из такой копии не получится. Чтобы выгрузить определенные расширения, нужно указать их имена в ключе –extension. Но при этом придется позаботиться о зависимостях — если в нашем случае выгрузить только схему util, то зависящая от расширения таблица public.t в резервную копию не попадет:
После создания расширения привилегии на его объекты сохраняются в системном каталоге. Если к моменту выгрузки привилегии изменились, pg_dump добавит в резервную копию команды для формирования новых привилегий.
Page 15: Итоги
Расширяемость — важнейшее свойство PostgreSQL
- Расширения — упаковка связанных объектов БД
- Механизм расширений содержит инструменты для обновления версий, поддержки работы pg_dump
Page 16: Практика
- Установите расширение uom и убедитесь, что оно появилось в списке доступных.
- Создайте расширение uom, не указывая версию. Какая версия создалась и какими скриптами?
- Добавьте в справочник футы и дюймы.
- Измените доступ к справочной таблице: привилегия SELECT должна быть только у специально созданной роли, а не у всех.
- Проверьте, как pg_dump выгружает объекты расширения: таблицу, тип, функции и операторы, содержимое таблицы, права доступа.
Комментарии преподавателя
Файлы расширения расположены в подкаталоге uom домашнего каталога пользователя student. Процесс установки аналогичен тому, что использовался в демонстрации.
При добавлении данных важно, чтобы у новых записей значение столбца predefined было false. Коэффициенты пересчета:
1 фут = 0,3048 м 1 дюйм = 0,0254 м
Page 17: 1. Установка расширения
Устанавливаем файлы расширения:
Проверим, что расширение доступно для загрузки в базу данных:
2. Создание расширения в базе данных
Создаем расширение uom в новой базе:
Версия расширения соответствует значению параметра default_version:
Поскольку для версии 1.2 есть файл uom–1.2.sql, то он и используется для создания расширения. А для тех, кто хочет перейти с 1.1 или с 1.0, имеются соответствующие пути обновления.
3. Расширение справочника
Добавляем футы и дюймы. Столбец predefined заполняется значением по умолчанию (false):
Сколько же дюймов в футе?
Page 18: 4. Изменение доступа
Создаем отдельную роль для доступа к таблице uom_ref:
Читать из таблицы может только новая роль:
5. pg\_dump и объекты расширений
Информация о том, содержимое каких таблиц будет выгружать pg_dump, сохраняется в pg_extension:
Запускаем pg_dump:
Page 19: Page 19
Проверим, как pg_dump выгружает объекты расширения: Таблица, тип, функции и операторы не выгружаются. Они будут созданы командой CREATE EXTENSION. В системе, где производится восстановление, должна быть та же версия расширения, что при выгрузке. Содержимое вновь добавленных строк таблицы выгружается в виде команды COPY. Права доступа к таблице uom_ref формируются такими, какими они были на момент запуска pg_dump. Для того чтобы правильно выгрузить права доступа, в системном каталоге сохраняется информация о правах на объекты, выданные скриптами создания расширений:
Без этого было бы невозможно сформировать команду REVOKE.