42.1. Обзор механизма работы триггеров событий
Триггер события срабатывает всякий раз, когда в базе данных, в которой он определён, происходит связанное с ним событие. В настоящий момент поддерживаются следующие события: login
, ddl_command_start
, ddl_command_end
, table_rewrite
и sql_drop
. Поддержка дополнительных событий может быть добавлена в будущих выпусках.
Событие login
происходит, когда аутентифицированный пользователь входит в систему. Любые ошибки в процедуре триггера для этого события могут помешать успешному входу в систему. Такие ошибки можно исправить, отключив событийные триггеры (см. ignore_event_trigger) и переподключившись к системе или перезапустив сервер в однопользовательском режиме (поскольку триггеры событий в этом режиме отключены). За дополнительными сведениями об однопользовательском режиме обратитесь к справке по postgres. Событийный триггер login
также срабатывает на резервных серверах. Во избежание проблем с подключением к резервным серверам, работающие на них триггеры входа не должны ничего писать в базу данных.
Событие ddl_command_start
происходит непосредственно перед выполнением команд CREATE
, ALTER
, DROP
, SECURITY LABEL
, COMMENT
, GRANT
и REVOKE
. Проверка на существование объекта перед срабатыванием триггера не производится. В качестве исключения, однако, это событие не происходит для команд DDL, обращающихся к общим объектам кластера базы данных — базам данных, табличным пространствам, ролям, а также к самим триггерам событий. Событие ddl_command_start
также происходит непосредственно перед выполнением команды SELECT INTO
, так как она равнозначна команде CREATE TABLE AS
.
Событие ddl_command_end
происходит непосредственно после выполнения команд из того же набора. Чтобы получить дополнительную информацию об операциях DDL, повлёкших произошедшее событие, вызовите функцию pg_event_trigger_ddl_commands()
, возвращающую множество, из кода обработчика события ddl_command_end
(см. Раздел 9.29). Заметьте, что этот триггер срабатывает после того, как эти действия имели место (но до фиксации транзакции), так что в системных каталогах можно увидеть уже изменённое состояние.
Событие sql_drop
происходит непосредственно перед событием ddl_command_end
для команд, которые удаляют объекты базы данных. Для получения списка удалённых объектов используйте возвращающую набор строк функцию pg_event_trigger_dropped_objects()
в триггере события sql_drop
(см. Раздел 9.29). Обратите внимание, что триггер выполняется после удаления объектов из таблиц системного каталога, поэтому их невозможно больше увидеть.
Событие table_rewrite
происходит непосредственно перед тем, как таблица будет перезаписана в результате определённых действий команд ALTER TABLE
и ALTER TYPE
. Хотя перезапись таблицы может быть вызвана и другими управляющими операторами, в частности CLUSTER
и VACUUM
, событие table_rewrite
для них не вызывается. Найти OID таблицы, которая была перезаписана, можно с помощью функции pg_event_trigger_table_rewrite_oid()
(см. Раздел 9.29). Причину (причины) перезаписи можно посмотреть с помощью функции pg_event_trigger_table_rewrite_reason()
.
Триггеры событий (как и прочие функции) не могут выполняться в прерванной транзакции. Поэтому, если команда DDL завершается ошибкой, соответствующие триггеры ddl_command_end
не сработают. И наоборот, если триггер ddl_command_end
завершился с ошибкой, последующие триггеры событий не сработают, так же как и сама команда не будет выполняться. Похожим образом, если триггер ddl_command_end
завершится ошибкой, действие команды DDL будет отменено, как это происходит при возникновении ошибки внутри транзакции.
Полный список команд, которые поддерживаются триггерами событий, можно найти в Разделе 42.2.
Для создания триггера события используется команда CREATE EVENT TRIGGER. Предварительно нужно создать функцию, со специальным возвращаемым типом event_trigger
. Данная функция не обязана возвращать значение (и может не возвращать). Возвращаемый тип служит лишь указанием на то, что функция будет вызываться из триггера события.
Если есть несколько триггеров на одно и то же событие, то они будут вызываться в алфавитном порядке по имени триггера.
В определении триггера можно использовать условие WHEN
, чтобы, например, триггер ddl_command_start
срабатывал только для отдельных команд, которые нужно перехватить. Триггеры событий часто используются для ограничения диапазона DDL-команд, доступных пользователям.
F.72. tsm_system_time
The tsm_system_time
module provides the table sampling method SYSTEM_TIME
, which can be used in the TABLESAMPLE
clause of a SELECT
command.
This table sampling method accepts a single floating-point argument that is the maximum number of milliseconds to spend reading the table. This gives you direct control over how long the query takes, at the price that the size of the sample becomes hard to predict. The resulting sample will contain as many rows as could be read in the specified time, unless the whole table has been read first.
Like the built-in SYSTEM
sampling method, SYSTEM_TIME
performs block-level sampling, so that the sample is not completely random but may be subject to clustering effects, especially if only a small number of rows are selected.
SYSTEM_TIME
does not support the REPEATABLE
clause.
This module is considered “trusted”, that is, it can be installed by non-superusers who have CREATE
privilege on the current database.
F.72.1. Examples
Here is an example of selecting a sample of a table with SYSTEM_TIME
. First install the extension:
CREATE EXTENSION tsm_system_time;
Then you can use it in a SELECT
command, for instance:
SELECT * FROM my_table TABLESAMPLE SYSTEM_TIME(1000);
This command will return as large a sample of my_table
as it can read in 1 second (1000 milliseconds). Of course, if the whole table can be read in under 1 second, all its rows will be returned.