Перейти к основному содержимому

Обзор поведения триггеров событий

примечание

Эта страница переведена при помощи нейросети GigaChat.

Триггер события срабатывает всякий раз, когда событие, с которым он связан, происходит в базе данных, для которой он определен. В настоящее время поддерживаются следующие события: login, ddl_command_start, ddl_command_end, table_rewrite и sql_drop. Поддержка дополнительных событий может быть добавлена в будущих выпусках.

Событие login возникает при входе аутентифицированного пользователя в систему. Любая ошибка в процедуре триггера для данного события может помешать успешному входу в систему. Такие ошибки можно обойти, установив значение параметра event_triggers равным false либо в строке подключения, либо в конфигурационном файле. Альтернативный способ заключается в перезапуске системы в однопользовательском режиме (так как в этом режиме триггеры событий отключаются). Подробности использования однопользовательского режима подробнее смотрите на странице справки по postgres. Событие login также будет возникать на серверах резервного копирования. Чтобы предотвратить недоступность серверов, такие триггеры должны избегать записи чего-либо в базу данных при выполнении на сервере резервного копирования. Также рекомендуется избегать длительных запросов в триггерах события login. Обратите внимание, например, отмена соединения в psql не приведет к отмене выполняющегося триггера login.

ССобытие ddl_command_start происходит непосредственно перед выполнением команды DDL. В данном контексте команды DDL выглядят следующим образом: CREATE, ALTER, DROP, COMMENT, GRANT, IMPORT FOREIGN SCHEMA, REINDEX, REFRESH MATERIALIZED VIEW, REVOKE, SECURITY LABEL. Событие ddl_command_start также происходит непосредственно перед выполнением команды SELECT INTO, поскольку это эквивалентно команде CREATE TABLE AS.

В качестве исключения, это событие не происходит для команд DDL, нацеленных на разделяемые объекты:

  • базы данных;
  • роли (определения ролей и членство в ролях);
  • табличные пространства;
  • привилегии параметров;
  • ALTER SYSTEM.

Это событие также не происходит для команд, нацеленных на сами триггеры событий.

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

Событие ddl_command_end происходит сразу после выполнения того же набора команд, что и ddl_command_start. Для получения более подробной информации о выполненных операциях DDL используйте возвращающую значение функцию pg_event_trigger_ddl_commands() из кода триггера события ddl_command_end. Обратите внимание, что триггер срабатывает после выполнения действий (но до подтверждения транзакции), поэтому системные каталоги могут быть прочитаны как уже измененные.

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

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

Событие table_rewrite происходит непосредственно перед перезаписью таблицы в результате выполнения команд ALTER TABLE и ALTER TYPE. Хотя для перезаписи таблицы доступны и другие операторы управления, такие как CLUSTER и VACUUM, событие table_rewrite ими не запускается. Чтобы найти OID перезаписанной таблицы, используйте функцию pg_event_trigger_table_rewrite_oid(), а чтобы узнать причину (причины) перезаписи, используйте функцию pg_event_trigger_table_rewrite_reason().

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

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

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

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

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