События MySQL были добавлены в MySQL 5.1.6 и предлагают альтернативу запланированным задачам и заданиям cron. События можно использовать для создания резервных копий, удаления устаревших записей, агрегирования данных для отчетов и т. Д. В отличие от стандартных триггеров, которые выполняются при определенных условиях, событие — это объект, который запускается с течением времени и иногда называется временным триггером . Вы можете запланировать запуск событий один раз или с периодическими интервалами, когда вы знаете, что трафик вашего сервера будет низким.
В этой статье я объясню, что вам нужно знать, чтобы начать использовать события: запуск планировщика событий, добавление событий для запуска один или несколько раз, просмотр существующих событий и изменение событий. Я также поделюсь с вами тем, как вы можете использовать события MySQL, используя запланированные посты в блоге, в качестве практического примера.
Запуск планировщика событий
Планировщик событий MySQL — это процесс, который работает в фоновом режиме и постоянно ищет события для выполнения. Прежде чем вы сможете создать или запланировать событие, вам необходимо сначала включить планировщик, выполнив следующую команду:
mysql> SET GLOBAL event_scheduler = ON;
Аналогично, чтобы отключить все события, вы должны использовать:
mysql> SET GLOBAL event_scheduler = OFF;
После запуска планировщика событий вы можете просмотреть его состояние в списке процессов MySQL.
mysql> ПОКАЗАТЬ ПРОЦЕССЛИСТ ... Id: 79 Пользователь: event_scheduler Хост: localhost дБ: NULL Команда: Демон Время 12 Состояние: ожидание в пустой очереди Информация: NULL
Работа с событиями
Важно отметить, что при создании события оно может выполнять только те действия, для которых пользователь MySQL, создавший событие, имеет привилегии для выполнения. Некоторые дополнительные ограничения включают в себя:
- Имена событий ограничены длиной до 64 символов.
- Начиная с MySQL 5.1.8, имена событий не чувствительны к регистру; имя каждого события должно быть уникальным независимо от регистра.
- События не могут быть созданы, изменены или удалены другим событием.
Вы не можете ссылаться на сохраненную функцию или пользовательскую функцию при настройке расписания событий.
Создание событий
В следующем примере создается событие:
DELIMITER |
CREATE EVENT myevent
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO
BEGIN
UPDATE mytable SET mycol = mycol + 1;
END |
DELIMITER ;
Это событие будет запущено один раз, через час после его создания. Операторы BEGIN
END
Поскольку точка с запятой необходима для завершения оператора UPDATE
CREATE EVENT
Вы можете просмотреть список всех существующих событий с SHOW EVENTS
mysql> ПОКАЗАТЬ СОБЫТИЯ ********************** 1. ряд ********************** Db: mysql Имя: Myevent Определитель: dbuser @ localhost Часовой пояс: СИСТЕМА Тип: ОДИН РАЗ Выполнить в: 2011-10-26 20:24:19 Значение интервала: NULL Интервальное поле: NULL Начинается: NULL Концы: NULL Статус: ВКЛЮЧЕНО Оригинатор: 0 character_set_client: utf8 collation_connection: utf8_general_ci
После того, как событие истекло, оно будет автоматически удалено, если вы явно не указали иное с предложением ON COMPLETION
CREATE EVENT myevent
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
ON COMPLETION PRESERVE
DO
BEGIN
UPDATE mytable SET mycol = mycol + 1;
END |
В этом примере, даже если событие истекло, оно все равно будет сохранено в базе данных, что позволит вам позже изменить его и запустить, или, возможно, вы просто захотите сохранить его для справки.
Чтобы навсегда удалить событие самостоятельно, вы можете использовать DROP EVENT
DROP EVENT myevent;
Чтобы указать повторяющееся событие, вы должны использовать предложение EVERY
CREATE EVENT myevent
ON SCHEDULE EVERY 1 HOUR
DO
BEGIN
UPDATE mytable SET mycol = mycol + 1;
END |
И вместо того, чтобы иметь событие, которое выполняется один раз или навсегда, вы также можете запланировать повторяющееся событие, которое будет действительным только в течение определенного периода времени, используя предложения START
END
CREATE EVENT myevent
ON SCHEDULE EVERY 1 HOUR
STARTS CURRENT_TIMESTAMP + INTERVAL 1 DAY
ENDS CURRENT_TIMESTAMP + INTERVAL 1 YEAR
DO
BEGIN
UPDATE mytable SET mycol = mycol + 1;
END |
В этом примере повторяющееся событие начнется завтра и будет продолжаться каждый час в течение всего года.
Что касается времени, указанный интервал может быть YEAR
MONTH
WEEK
DAY
HOUR
MINUTE
SECOND
Имейте в виду, что ключевые слова приведены в единственном числе; писать что-то вроде INTERVAL 5 MINUTE
Обновление событий
Если вы хотите изменить поведение существующего события, а не удалять его и создавать заново, вы можете использовать ALTER EVENT
Например, чтобы изменить расписание предыдущего события, которое будет запускаться каждый месяц, начиная с некоторой даты в будущем в 1 час ночи, вы должны использовать следующее:
ALTER EVENT myevent
ON SCHEDULE EVERY 1 MONTH
STARTS '2011-12-01 01:00:00' |
Чтобы обновить событие с другим набором запросов, вы должны использовать:
ALTER EVENT myevent
DO
BEGIN
INSERT INTO mystats (total)
SELECT COUNT(*) FROM sessions;
TRUNCATE sessions;
END |
Чтобы переименовать событие, вы должны указать предложение RENAME
ALTER EVENT myevent
RENAME TO yourevent;
Планирование публикации блога
Чтобы я мог показать вам практический пример, допустим, у вас есть блог, и вы хотите запланировать публикацию сообщений в будущем. Одним из способов достижения этого является добавление метки времени и опубликованного флага в записи базы данных. Сценарий cron будет выполняться раз в минуту, чтобы проверять временные метки и устанавливать флажки для всех публикаций, которые должны быть опубликованы. Но это не кажется очень эффективным. Другой способ добиться этого — использовать события MySQL, которые будут срабатывать, когда вы захотите опубликовать сообщение.
Ваша форма записи в блоге может иметь флажок, который, если установлен, указывает, что это запланированная запись. Кроме того, в форме будут поля ввода для ввода даты и времени публикации сообщения. Принимающий скрипт будет отвечать за добавление записи блога в базу данных и управление событиями для ее планирования, если это не будет немедленная публикация. Соответствующий код выглядит следующим образом:
<?php
// establish database connection and filter incoming data
// ...
// insert blog post with pending status, get id assigned to post
$query = "INSERT INTO blog_posts (id, title, post_text, status)
VALUES (NULL, :title, :postText, 'pending')";
$stm = $db->prepare($query);
$stm->execute(array(":title" => $title, ":postText" => $text));
$id = $db->lastInsertId();
// is this a future post?
if (isset($_POST["schedule"], $_POST["time"])) {
$scheduleDate = strtotime($_POST["time"]);
$query = "CREATE EVENT publish_:id
ON SCHEDULE AT FROM_UNIXTIME(:scheduleDate)
DO
BEGIN
UPDATE blog_posts SET status = 'published' WHERE id = :id;
END";
$stm = $db->prepare($query);
$stm->execute(array(":id" => $id, ":scheduleDate" => $scheduleDate));
}
// this is not a future post, publish now
else {
$query = "UPDATE blog_posts SET status = 'published' WHERE id = :id";
$stm = $db->prepare($query);
$stm->execute(array(":id" => $id));
}
Когда сообщение хранится в базе данных, оно сохраняется с ожидающим статусом. Это дает вам возможность запланировать событие, если это запланированное сообщение, в противном случае статус может быть немедленно обновлен до опубликованного.
Если вам нужно будет отредактировать сообщение позже, вы можете удалить событие с помощью DROP EVENT IF EXISTS
Резюме
Теперь у вас должно быть четкое представление о том, что такое события MySQL, а также о том, как создавать собственные события и управлять ими. Хотя события не являются заменой для заданий cron или запланированных задач, поскольку события не могут выполнять внешний код, такой как сценарии PHP, они являются полезной альтернативой для зависящих от времени задач, специфичных для базы данных MySQL. Как всегда, если вы заинтересованы в получении дополнительной информации, обязательно ознакомьтесь с официальной документацией .
Изображение через Гарся / Shutterstock