События MySQL EVENT
выполняются специальным потоком планировщика событий. При обращении к планировщику событий, на самом деле идет обращение к его потоку. За работу планировщика отвечает глобальная системная переменная event_scheduler
, которая определяет, включен ли планировщик событий и работает ли он на сервере. Он имеет одно из следующих значений:
ON
: планировщик событий запущен. Поток планировщика событий запускается и выполняет все запланированные события. ON
- это значение event_scheduler
по умолчанию.OFF
: Планировщик событий остановлен. Поток планировщика событий не запускается, не отображается в выходных данных SHOW PROCESSLIST;
и запланированные события не выполняются.DISABLED
: это значение отключает планировщик событий. Когда планировщик событий отключен, то поток планировщика событий не запускается. Кроме того, состояние планировщика событий нельзя изменить во время выполнения.Посмотреть включен ли планировщик событий можно командой SHOW VARIABLES LIKE 'event_scheduler';
Если статус планировщика событий НЕ DISABLED
, то переменную event_scheduler
можно переключать между ON
и OFF
. Хотя ON
и OFF
имеют числовые эквиваленты, значение, отображаемое для event_scheduler
с помощью SHOW VARIABLES;
, всегда имеет значение OFF
, ON
или DISABLED
. DISABLED
не имеет числового эквивалента. По этой причине ON
и `OFF обычно предпочтительнее, чем 1 и 0 при установке этой переменной:
SET GLOBAL event_scheduler = ON; SET @@GLOBAL.event_scheduler = ON; SET GLOBAL event_scheduler = 1; SET @@GLOBAL.event_scheduler = 1;
Примечание: Включение планировщика при помощи установки переменной
event_scheduler = ON
не гарантирует его автоматическое включение после перезапуска сервера MySQL.
Чтобы планировщик событий автоматически включался при старте MySQL-сервера необходимо использовать один из следующих двух методов:
--event-scheduler=ON
, в качестве параметра командной строки;event_scheduler = ON
в файле конфигурации сервера (my.cnf
или my.ini
в системах Windows), например, в разделе [mysqld]
.Внимание! При отключенном планировщике
event_scheduler = DISABLED
можно создавать операторы управления событиями. Никаких предупреждений или ошибок в таких случаях не генерируется (при условии, что операторы сами по себе верны). Однако запланированные события не могут выполняться, пока для этой переменной не будет установлено значение ON (или 1). Как только это будет сделано, поток планировщика событий выполняет все события, условия планирования которых удовлетворены.
-- DROP EVENT IF EXISTS event_name -- CREATE [DEFINER=user] EVENT [IF NOT EXISTS] event_name ON SCHEDULE AT timestamp [+ INTERVAL interval ... ] | EVERY interval [STARTS ...][ENDS ...] [ON COMPLETION [NOT] PRESERVE] [ENABLE | DISABLE | DISABLE ON SLAVE] [COMMENT 'string'] DO [BEGIN] -- Тело события может содержать объявления -- переменных `DECLARE`, циклы, например `LOOP`, -- встроенные в MySQL и хранимые процедуры/функции и -- другие операторы структуры и/или управления потоком. [END;]
Событие связано со схемой. Если схема не указана как часть имени события event_name
, то предполагается схема по умолчанию (текущая). Чтобы создать событие в определенной схеме, необходимо использовать синтаксис "имя_схемы.имя_события
".
Инструкция CREATE EVENT
требует привилегии EVENT
для схемы, в которой должно быть создано событие. Если присутствует предложение DEFINER
, требуемые привилегии зависят от значения пользователя.
Минимальные требования для действительного оператора CREATE EVENT
следующие:
CREATE EVENT
плюс имя события event_name
, которое однозначно идентифицирует событие в схеме базы данных.ON SCHEDULE
, которое определяет, когда и как часто выполняется событие.DO
, содержащее оператор SQL, который должен быть выполнен событием._Это пример минимального оператора CREATE EVENT
:
CREATE EVENT myevent ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO UPDATE myschema.mytable SET mycol = mycol + 1;
Здесь создается событие с именем myevent
. Это событие выполняется один раз - через час после его создания, путем выполнения инструкции SQL, которая увеличивает значение столбца mycol
таблицы myschema.mytable
на 1.
Имя события myevent
должно быть действительным идентификатором MySQL с максимальной длиной 64 символа. Имена событий не чувствительны к регистру, поэтому в одной схеме не может быть двух событий с именами myevent
и MyEvent
. В целом, правила, определяющие имена событий, такие же, как и правила для имен хранимых подпрограмм.
DEFINER=user
:Инструкция DEFINER
указывает учетную запись MySQL, которая будет использоваться при проверке прав доступа во время выполнения процедуры/функции. Если присутствует предложение DEFINER
, то значением пользователя должна быть учетная запись MySQL, указанная как 'user_name'@'host_name'
, CURRENT_USER
или CURRENT_USER()
. Разрешенные значения пользователей зависят от имеющихся привилегий.
Если инструкция DEFINER
опущена, то по умолчанию является пользователь, выполняющий оператор CREATE EVENT
. Это то же самое, что явно указать DEFINER = CURRENT_USER
.
Подробнее об инструкции DEFINER
смотрите в материале "Хранимые процедуры и функции в БД MySQL".
IF NOT EXISTS
:Инструкция IF NOT EXISTS
имеет то же значение что и для CREATE TABLE: если событие с именем event_name
уже существует в той же схеме, то никаких действий не предпринимается и ошибка не возникает. (Однако в таких случаях генерируется предупреждение.)
ON COMPLETION [NOT] PRESERVE
:Использование предложения ON COMPLETION [NOT] PRESERVE
актуально только в случаях, когда событие конечно, т.е. у события задается конечная дата (ключевое слово ENDS date
) или событие имеет одноразовый характер ключевое слово AT
. ПО УМОЛЧАНИЮ, как только событие истекает, оно немедленно удаляется (поведение ON COMPLETION NOT PRESERVE
). Поведение по умолчанию можно переопределить, указав ON COMPLETION PRESERVE
, тогда событие останется в памяти.
ENABLE | DISABLE | DISABLE ON SLAVE
:Можно создать событие, но запретить его активность с помощью ключевого слова DISABLE
. В качестве альтернативы можно использовать ENABLE
что сделает явным статус по умолчанию. Это поведение наиболее полезно в сочетании с ALTER EVENT
(при изменении события).
Вместо ENABLE
или DISABLE
может появиться третье значение: DISABLE ON SLAVE
, которое устанавливается для состояния события на реплике, т.е. событие было создано на исходном сервере репликации и реплицировано на реплику, но на реплике не выполняется.
COMMENT
:Инструкция COMMENT
является расширением MySQL и может использоваться для описания события EVENT
. Комментарий может быть любой строкой длиной до 64 символов. Текст комментария, являющийся строковым литералом, должен быть заключен в кавычки.
Например:
CREATE EVENT e_hourly ON SCHEDULE EVERY 1 HOUR COMMENT 'Clears out sessions table each hour.' DO DELETE FROM site_activity.sessions;
AT timestamp [+ INTERVAL interval ... ]
:Временная метка AT
используется для одноразового события. Она указывает, что событие выполняется только один раз в дату и время, заданные отметкой времени timestamp
, которая должна включать как дату, так и время, или должна быть выражением, которое разрешается в значение даты и времени. Для этой цели можно использовать значение типа DATETIME
или TIMESTAMP
. Если дата уже в прошлом, то появляется предупреждение: "Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation."
Можно использовать функцию CURRENT_TIMESTAMP
, чтобы указать текущую дату и время. В таком случае событие действует, как только оно создано.
Чтобы создать событие, которое произойдет в какой-то момент в будущем относительно текущей даты и времени, например, выраженное фразой "через три недели", можно использовать необязательное предложение + INTERVAL interval
. Часть interval
состоит из двух частей, количества и единицы времени, и следует правилам синтаксиса, описанным в материале "Встроенные БД MySQL интервалы времени", за исключением того, что при определении события нельзя использовать микросекунды. С некоторыми типами интервалов могут использоваться комплексные единицы времени. Например, "две минуты и десять секунд" можно выразить как + INTERVAL '2:10' MINUTE_SECOND
.
Также можно комбинировать интервалы. Например, AT CURRENT_TIMESTAMP + INTERVAL 3 WEEK + INTERVAL 2 DAY
эквивалентно "через три недели и два дня". Каждая часть такого предложения должна начинаться с + INTERVAL
.
EVERY interval [STARTS ...][ENDS ...]
:Чтобы повторять действия через равные промежутки времени, необходимо использовать предложение EVERY
. За ключевым словом EVERY
следует интервал interval
, как описано в ключевом слове AT
. Внимание! предложение + INTERVAL
не используется с инструкцией EVERY
. Например, EVERY 6 WEEK
означает "каждые шесть недель".
Хотя предложения + INTERVAL
не разрешены в инструкции EVERY
, можно использовать те же комплексные единицы времени, которые разрешены в + INTERVAL
.
Предложение EVERY
может содержать необязательное предложение STARTS
. За STARTS
следует значение метки времени, которое указывает, когда действие должно начать повторяться, а также может использовать интервал + INTERVAL
, чтобы указать количество времени "с этого момента". Например, EVERY 3 MONTH STARTS CURRENT_TIMESTAMP + INTERVAL 1 WEEK
означает "каждые три месяца, начиная с одной недели". Точно так же можно выразить "каждые две недели, начиная с этого момента через шесть часов и пятнадцать минут" как EVERY 2 WEEK STARTS CURRENT_TIMESTAMP + INTERVAL '6:15' HOUR_MINUTE
. Если не указывать STARTS
, то это то же самое, что использовать STARTS CURRENT_TIMESTAMP
, т. е. действие, указанное для события, начинает повторяться сразу после создания события.
Предложение EVERY
может содержать необязательное предложение ENDS
. За ключевым словом ENDS
следует значение метки времени, которое сообщает MySQL, когда событие должно прекратить повторяться. С ключевым словом ENDS
также можно использовать интервал + INTERVAL
. Например, EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEK
эквивалентно "каждые двенадцать часов, начиная с тридцати минут и заканчивая через четыре недели". Отсутствие использования ENDS
означает, что событие продолжает выполняться бесконечно.
Ключевое слово ENDS
поддерживает тот же синтаксис для комплексных единиц времени, что и STARTS
. В инструкции EVERY
можно использовать STARTS
, ENDS
, и то, и другое.
Если повторяющееся событие не завершается в течение интервала планирования, то результатом может быть одновременное выполнение нескольких экземпляров события. Если это нежелательно, то необходимо установить механизм для предотвращения одновременных экземпляров. Например, можно использовать функцию GET_LOCK()
или блокировку строк или таблиц.
DO [BEGIN ... END]
:Предложение DO
определяет действие, выполняемое событием, и состоит из оператора SQL. В качестве оператора действия для запланированного события можно использовать почти любой допустимый оператор MySQL, который можно использовать в хранимой процедуре. Например, следующее событие e_hourly
удаляет все строки из таблицы сеансов один раз в час, где эта таблица является частью схемы site_activity
:
CREATE EVENT e_hourly ON SCHEDULE EVERY 1 HOUR COMMENT 'Clears out sessions table each hour.' DO DELETE FROM site_activity.sessions;
Схема, к которой принадлежит событие, является схемой по умолчанию для ссылок на таблицы в предложении DO
. Любые ссылки на таблицы в других схемах должны быть дополнены правильным именем схемы.
Как и в случае с хранимыми процедурами/функциями, в предложении DO
можно использовать синтаксис составного оператора, используя ключевые слова BEGIN
и END
:
delimiter | CREATE EVENT e_daily ON SCHEDULE EVERY 1 DAY COMMENT 'Saves total number of sessions then clears the table each day' DO BEGIN INSERT INTO site_activity.totals (time, total) SELECT CURRENT_TIMESTAMP, COUNT(*) FROM site_activity.sessions; DELETE FROM site_activity.sessions; END | delimiter ;
В этом примере используется команда delimiter
для изменения разделителя операторов. Подробнее о команда delimiter
и блоке BEGIN ... END
смотрите в материале "Хранимые процедуры и функции в БД MySQL".
В событии возможны более сложные составные операторы, например, используемые в хранимых подпрограммах. В этом примере используются локальные переменные, обработчик ошибок и конструкция управления потоком:
delimiter | CREATE EVENT e ON SCHEDULE EVERY 5 SECOND DO BEGIN DECLARE v INTEGER; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; SET v = 0; WHILE v < 5 DO INSERT INTO t1 VALUES (0); UPDATE t2 SET s1 = s1 + 1; SET v = v + 1; END WHILE; END | delimiter ;
Передать параметры напрямую в события или из них НЕВОЗМОЖНО, однако внутри события можно вызвать хранимую процедуру с параметрами:
CREATE EVENT e_call_myproc ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY DO CALL myproc(5, 27);
Имена событий обрабатываются без учета регистра. Например, в одной базе данных не может быть двух событий с именами anEvent
и AnEvent
.
Событие не может быть создано, изменено или удалено из сохраненной программы, если имя события указано с помощью переменной. Событие также не может создавать, изменять или удалять сохраненные процедуры или триггеры.
Операторы DDL для событий запрещены, пока действует оператор LOCK TABLES
.
Время события с использованием интервалов YEAR
, QUARTER
, MONTH
и YEAR_MONTH
определяется в месяцах. Те, которые используют любой другой интервал, разрешаются в секундах. Невозможно заставить события, запланированные на одну и ту же секунду, выполняться в заданном порядке. Кроме того, из-за округления, характера многопоточных приложений и того факта, что для создания событий и подачи сигнала об их выполнении требуется ненулевое время, события могут задерживаться на 1–2 секунды. Однако время, отображаемое в столбце LAST_EXECUTED
таблицы INFORMATION_SCHEMA.EVENTS
, всегда соответствует времени выполнения события с точностью до одной секунды.
Каждое выполнение операторов, содержащихся в теле события, происходит в новом соединении. Таким образом, в данном пользовательском сеансе эти операторы не влияют на количество операторов сервера, таких как Com_select
и Com_insert
(отображаются с помощью SHOW STATUS;
). Однако такие счетчики обновляются в глобальной области.
События не поддерживают время, позднее окончания эпохи Unix. Это примерно начало 2038 года. Такие даты специально не разрешены Планировщиком событий.
Ссылки на хранимые функции, загружаемые функции и таблицы в предложениях ON SCHEDULE
инструкций CREATE EVENT
и ALTER EVENT
не поддерживаются. Такие ссылки не допускаются.