Сегодня мы с вами узнаем, что такое расширения (extensions). Как их устанавливать? Как ими управлять?
Что часто говорят, когда вспоминают плюсы PostgreSQL?
Так вот, как раз за легкую расширяемость и отвечают расширения. Давайте посмотрим, зачем реализован такой механизм, и узнаем, как его рационально использовать.
С самого начала предполагалось, что PostgreSQL как база данных будет расширяться. Под этим понимается, что в нем можно:
И для того чтобы творить все эти улучшения, не требуется вносить какие-либо изменения в код самого сервера. Как раз для этого и реализован механизм расширений.
Общая архитектура:
В большинстве случаев для расширения возможностей системы PostgreSQL необходимо создать несколько разнообразных объектов базы данных, например, описания типов, набор функций и операторов. А для того чтобы управлять этой логически связанной группой объектов, их и упаковывают в расширения (extension). Этот подход не нов и много где встречается.
Если разработанное кем-то расширение находит в сообществе широкий спрос, разработчики могут включить его код в дистрибутив самого сервера в качестве расширения (директория - contrib), а если и там оно будет сильно востребовано - может перекочевать в ядро. И многие популярные расширения уже прошли по этому пути.
Некоторые расширения входят в состав основной распространяемой версии системы PostgreSQL, но не подключаются автоматически при ее установке. Для их подключения достаточно выполнить команду CREATE EXTENSION, указав имя расширения в качестве аргумента.
Но не нужно забывать, что помимо улучшений и расширения функционала этот же механизм может принести с собой и некую долю хаоса:
Хорошо написанное расширение добавит функционал в систему, а плохо или небрежно написанное — может её убить.
Механизм расширений сам по себе не добавляет новые возможности, однако позволяет организовывать модули расширения, описывать действия, необходимые для смены версий расширения, обеспечивает согласованную обработку объектов, входящих в расширение, при создании резервных копий и выполнении других административных действий.
Если в общих чертах, то:
Для системы PostgreSQL каждое расширение описывается.
Где брать расширения?
Традиционно — это каталог /contrib. В нем собраны расширения, которые поставляются вместе с PostgreSQL, отдельно их можно скачать с postgresql.org (их поддерживает команда разработчиков PostgreSQL). pgxn.org — сеть расширений для PostgreSQL по образу и подобию аналогичной сети для PERL. GitHub.com — тоже никто не отменял. В общем, источников для поиска достаточно много. А можно разработать собственное расширение.
Как установить расширение?
Для управления расширениями в PostgreSQL используются команды SQL. Так, загрузка объектов расширения в базу данных выполняется при создании расширения (CREATE EXTENSION). Переход на новую версию — ALTER EXTENSION. А удалить расширения со всеми его объектами можно командой DROP EXTENSION. Не требуется разрабатывать отдельный uninstall скрипт. Для работы этих команд в составе расширений должны быть специальные файлы.
Кроме этого, в состав расширения могут входить и другие файлы, например, объектный код функций, написанных на процедурных языках, требующих компиляции, файлы *.sql для версионной миграции этого расширения и другие. Но, с точки зрения управления расширениями, такие файлы не важны.
При выполнении команды CREATE EXTENSION механизм расширений проверяет наличие управляющего файла в каталоге SHAREDIR/extension. Расположение SHAREDIR можно посмотреть командой:
$ pg_config --sharedir
Имя управляющего файла состоит из имени расширения, к которому добавляется «.control»
. Управляющий файл имеет формат конфигурационных файлов PostgreSQL и состоит из пар «ключ = значение».
Помимо управляющего файла требуется еще файл SQL с командами на создание объектов БД. Имя файла SQL зависит от устанавливаемой версии расширения. Ее можно явно указать в параметре VERSION команды CREATE EXTENSION. По умолчанию будет использоваться версия из параметра default_version управляющего файла. Имя файла SQL строится по шаблону «имя--версия.sql», где версия не обязательно должна состоять из цифр. Она может включать и другие символы (кроме «--» , а также «-» в начале или в конце). Список доступных версий расширений находится в таблице системного каталога pg_available_extension_versions. Строки файла SQL, начинающиеся на \echo, механизм расширений считает комментариями. Для предотвращения случайного запуска файла из psql обычно в начало файла SQL добавляют вот такую строку с предупреждением и завершают ее командой \quit:
\echo Use "CREATE EXTENSION имя" to load this file. \quit
В файле SQL можно использовать кириллицу, предварительно указав кодировку символов в параметре encoding управляющего файла. Например, можно задать русскоязычный комментарий к расширению в команде COMMENT ON EXTENSION.
Расширение как объект базы данных не принадлежит ни одной схеме. Но все объекты расширения создаются в какой-то схеме. При необходимости в SQL-файле расширения можно создавать новые схемы. Хотя это и не обязательно, но обычно все объекты расширения размещают в одной схеме. Схему для размещения объектов можно явно указать в команде CREATE EXTENSION или задать в параметре schema управляющего файла. Иначе будет использоваться первая схема из параметра конфигурации search_path. Выбранная схема явно устанавливается в search_path в начале выполнения файла SQL. Внутри файла можно обращаться к этой схеме, используя макроподстановку @extschema@. Если параметр расширения relocatable установить в true (по умолчанию false), то объекты расширения можно будет переносить в другую схему командой:
ALTER EXTENSION имя SET SCHEMA новая_схема;
Если со временем требуется изменить существующие объекты расширения или добавить новые, то выпускается новая версия. В управляющем файле новой версии расширения обычно меняется параметр default_version. А при установке возможны две ситуации:
Предыдущая версия расширения не была установлена. Поэтому можно подготовить файл SQL для новой версии, включающий создание всех объектов расширения.
Для тех, у кого установлена предыдущая версия расширения, следует подготовить файл SQL для обновления версии. Формат имени файла обновления следующий:
старая_версия--новая_версия.sql
Внутри такого файла должны быть только команды, обновляющие объекты расширения со старой версии на новую. Само обновление выполняется командой:
ALTER EXTENSION имя UPDATE;
Перенести данные:
Утилита pg_dump обрабатывает расширения особым образом. Чтобы не потерять зависимости между объектами, нельзя просто выгружать команды определения объектов расширения (CREATE FUNCTION, CREATE VIEW, CREATE TABLE,…). Поэтому в копию, выгруженную pg_damp'ом, включается команда CREATE EXTENSION IF NOT EXISTS имя WITH SCHEMA схема;
При восстановлении из такой копии расширение будет заново создано со всеми объектами и связями. Перед восстановлением нужно убедиться, что в системе установлена такая же версия расширения, что и при создании копии.
А вот данные таблиц, которые были внесены пользователями уже после создания, при переносе будут потеряны!
По умолчанию строки таблиц, вставленные после установки расширения, не будут выгружаться утилитой pg_dump. Если же требуется включить содержимое таблиц в выгрузку pg_dump, то в файле SQL расширения нужно вызвать для каждой таблицы функцию pg_extension_config_dump()
CREATE TABLE tab ...
SELECT pg_extension_config_dump('tab'::regclass);
Функция имеет два параметра. Первый — это OID таблицы, второй (необязательный) — WHERE. Эту функцию pg_dump будет применять к таблице при выгрузке. Она же используется и для последовательностей, которые могут быть связаны с таблицей. В вывод pg_dump будет записываться вызов функции setval, устанавливающий последнее полученное из последовательности значение. Функцию pg_extension_config_dump() можно вызывать только из файлов SQL-расширения!
Давайте посмотрим, где лежат файлы расширений, идущих, так сказать, в комплекте:
ls -l $(pg_config --sharedir)/extension/
total 1096
-rw-r--r-- 1 root root 274 Nov 12 11:13 adminpack--1.0--1.1.sql
-rw-r--r-- 1 root root 1535 Nov 12 11:13 adminpack--1.0.sql
-rw-r--r-- 1 root root 176 Nov 12 11:13 adminpack.control
-rw-r--r-- 1 root root 704 Nov 12 11:13 amcheck--1.0.sql
-rw-r--r-- 1 root root 154 Nov 12 11:13 amcheck.control
...
А какие расширения уже установлены?
postgres=# \dx
List of installed extensions
Name | Version | Schema | Description
---------+---------+------------+------------------------------
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
(1 row)
Давайте установим что-нибудь простенькое из списка выше:
postgres=# CREATE EXTENSION pg_trgm;
CREATE EXTENSION
postgres=# \dx
List of installed extensions
Name | Version | Schema | Description
---------+---------+------------+-------------------------------------------------------------------
pg_trgm | 1.3 | public | text similarity measurement and index searching based on trigrams
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
(2 rows)
А если подробнее?
postgres=# \dx+ pg_trgm;
Objects in extension "pg_trgm"
Object description
--------------------------------------------------------------------------------------------------
function gin_extract_query_trgm(text,internal,smallint,internal,internal,internal,internal)
function gin_extract_value_trgm(text,internal)
function gin_trgm_consistent(internal,smallint,text,integer,internal,internal,internal,internal)
function gin_trgm_triconsistent(internal,smallint,text,integer,internal,internal,internal)
function gtrgm_compress(internal)
function gtrgm_consistent(internal,text,smallint,oid,internal)
function gtrgm_decompress(internal)
function gtrgm_distance(internal,text,smallint,oid,internal)
function gtrgm_in(cstring)
function gtrgm_out(gtrgm)
function gtrgm_penalty(internal,internal,internal)
function gtrgm_picksplit(internal,internal)
function gtrgm_same(gtrgm,gtrgm,internal)
function gtrgm_union(internal,internal)
function set_limit(real)
function show_limit()
function show_trgm(text)
function similarity(text,text)
function similarity_dist(text,text)
function similarity_op(text,text)
function word_similarity(text,text)
function word_similarity_commutator_op(text,text)
function word_similarity_dist_commutator_op(text,text)
function word_similarity_dist_op(text,text)
function word_similarity_op(text,text)
operator %(text,text)
operator %>(text,text)
operator <%(text,text)
operator <->(text,text)
operator <->>(text,text)
operator <<->(text,text)
operator class gin_trgm_ops for access method gin
operator class gist_trgm_ops for access method gist
operator family gin_trgm_ops for access method gin
operator family gist_trgm_ops for access method gist
type gtrgm
(36 rows)
${base_domain}
).Чтобы начать выполнение задания, укажите в настройках вашу должность, название компании и аккаунт в Telegram
Заполнить