MySQL Event Scheduler или встроенный диспетчер событий в MySQL
В MySQL 5.1 появился свой планировщик задач! Ранее, мне и многим другим разработчикам приходилось использовать cron для таких целей, как "подчистка устаревшей информации" или "пересчет счетчиков" в базе данных и т.д.
Включение планировщика
Планировщик по умолчанию выключен, для того чтобы его включить надо добавить в my.ini или в my.cnf
[mysqld] event_scheduler = on
Так же вы можете для конкретной сессии запустить планировщик в mysql-консоле
mysql> set global event_scheduler = ON;
Для проверки, работает ли планировщик, выполните запрос:
mysql> show variables like 'event_scheduler'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | event_scheduler | ON | +-----------------+-------+ 1 row in set (0.00 sec)
Официальное руководство по настройке.
Создание задания
Синтаксис достаточно прост, при создании задания необходимо обязательно указать:
- Имя задания (event_name)
- Интервал или точное время (schedule и interval)
- SQL-запрос для выполнения (sql_statement)
CREATE [DEFINER = { user | CURRENT_USER }] EVENT [IF NOT EXISTS] event_name ON SCHEDULE schedule [ON COMPLETION [NOT] PRESERVE] [ENABLE | DISABLE | DISABLE ON SLAVE] [COMMENT 'comment'] DO sql_statement; schedule: AT timestamp [+ INTERVAL interval] ... | EVERY interval [STARTS timestamp [+ INTERVAL interval] ...] [ENDS timestamp [+ INTERVAL interval] ...] interval: quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE | WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE | DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}
Так же вы можете указать:
- DEFINER - имя пользователя, от кого запускать задание (с его правами соответственно)
- COMMENT - комментарий
- ON COMPLETION PRESERVE - задание после выполнения сохраняется
- ON COMPLETION NOT PRESERVE - задание выполняется один раз, после чего уничтожается из списка заданий (по умолчанию)
Пример короткой записи:
CREATE EVENT `myevent` ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 10 MINUTE ON COMPLETION PRESERVE DO UPDATE `myschema`.`mytable` SET `mycol` = `mycol` + 1;
Официальное руководство по CREATE EVENT
Изменение задания
При изменении, вы можете сменить владельца, переименовать название, изменить SQL-запрос и поменять другие свойства задания.
ALTER [DEFINER = { user | CURRENT_USER }] EVENT event_name [ON SCHEDULE schedule] [ON COMPLETION [NOT] PRESERVE] [RENAME TO new_event_name] [ENABLE | DISABLE | DISABLE ON SLAVE] [COMMENT 'comment'] [DO sql_statement]
Для отображения всех свойств задания используйте:
SELECT * FROM `INFORMATION_SCHEMA`.`EVENTS` WHERE `EVENT_NAME` = 'myevent' AND EVENT_SCHEMA = 'myschema'\G
*************************** 1. row *************************** EVENT_CATALOG: NULL EVENT_SCHEMA: myschema EVENT_NAME: myevent DEFINER: john@smith EVENT_BODY: SQL EVENT_DEFINITION: INSERT INTO myschema.mytable VALUES (UNIX_TIMESTAMP()) EVENT_TYPE: RECURRING EXECUTE_AT: NULL INTERVAL_VALUE: 5 INTERVAL_FIELD: SECOND SQL_MODE: NULL STARTS: 0000-00-00 00:00:00 ENDS: 0000-00-00 00:00:00 STATUS: ENABLED ON_COMPLETION: NOT PRESERVE CREATED: 2006-02-09 22:36:06 LAST_ALTERED: 2006-02-09 22:36:06 LAST_EXECUTED: NULL EVENT_COMMENT: 1 row in set (0.00 sec)
Либо используйте:
show events like "event_name%"\G
Официальное руководство по ALTER EVENT
Удаление задания
DROP EVENT [IF EXISTS] event_name
Официальное руководство по DROP EVENT
Диспетчер событий и привилегии в MySQL
Официальное руководство по установке привелегий
Примеры использования
Задача: Удаление не активированных учетных записей пользователей, которые не активировались в течении 3-х дней. Запускать событие необходимо каждый день.
CREATE EVENT `not_active_users` ON SCHEDULE EVERY 1 DAY DO DELETE FROM `users` WHERE `active` = 'not', UNIX_TIMESTAMP(`date`) >= UNIX_TIMESTAMP(NOW()) - (3 * 24 * 3600);
Задача: А теперь сменим для задания "not_active_users" временной интервал.
ALTER EVENT `not_active_users` ON SCHEDULE EVERY 12 HOUR;
Задача: Удалить задание.
DROP EVENT `not_active_users`;
Официальные страницы руководства: Using the Event Scheduler
Комментарии
Для событий исполняемых с определенной периодичностью, можно также указать время старта и время прекращения цикличного выполнения, например для примера приведенного в статье:
CREATE EVENT
not_active_users
ON SCHEDULE
EVERY 1 DAY START '2009-06-12 23:59:59' END CURRENT_TIMESTAMP + INTERVAL 1 WEEK
DO
DELETE FROM
users
WHERE
active
= 'not', UNIX_TIMESTAMP(date
) >= UNIX_TIMESTAMP(NOW()) - (3 * 24 * 3600);Событие исполнится -2009-06-12 23:59:59 и не будет исполнятся через 1 неделю, подробнее смотрите http://dev.mysql.com/doc/refman/5.1/en/create-event.html
В популярном менеджере EMS можно работать с событиями, для версий совместимых с соответствующей версией MySQL.
Спасибо Константин, за очень ценный комментарий!
Эвенты - классная штука, ...на ранних версиях mysql правда был баг с временем срабатывания, но MySQL AB уже пофиксил. А вот ещё нашел отличный редактор для mysql - Devart dbForge studio for MySQL, там для событий ещё более удобный редактор с настройками объектов.
Devart dbForge studio for MySQL, русская бесплатная
alexeym, да, я эту софтину юзал :)
выполняю в консоли следующий код
пишет ошибку
должен ли я в консоли заранее выполнить запрос для выбора базы данных
Какая версия mysql?
5.1
Да, выбери БД и еще покажи
Vatiable_name Value
event_scheduler ON
1 row in set
мистика емае
короче в топку, буду на C# делать сервак
быстро ты сдался... ты use database_name то делал?
дай доступ к бд - сам посмотрю
а может хостер запретить эту функцию в целях безопасности или предотвращения нагрузки сервера?
проверил состояние пишет:
event_scheduler OFF - означает что выключен хостером или просто выключен и нуна его включить другим запросом (каким запросом?) ? ;
хм... кстати у меня нету доступа к файлам my.ini и my.cnf да и вообще где они должны быть расположены?
эх... Access denied; you need the SUPER privilege for this operation - походу я сосу (пардон)...
а у хостер есть смысл просить эту функцию как вы думаете?
=)
Спросить всегда можно, некоторые идут на уступки. Но лучше бы вы взяли вдс (300-600 руб в мес)
Скажите пожалуйста, такой планировщик можно настроить на автоматическое создание дампа (бэкапа) базы данных в конкретное время(в конкретные дни)?
CREATE EVENT
not_active_users
ON SCHEDULE
EVERY 1 DAY
DO
Можно как то прикрутить такую операцию?
Смотрите http://adw0rd.ru/2009/mysqldump-and-cheat-sheet/#online-backup
Либо только через cron и т.д., т.е. вне MySQL
ps. http://dev.mysql.com/doc/refman/5.0/en/backup-methods.html
А существует ли стандартный механизм проверки "выполняется ли событие" для исключения ситуаций, когда за интервал между срабатывания не успевает выполниться первое срабатывание события?
Ну если подумать, то получается что вам нужен некий коллбек, который срабатывает "когда событие выполнилось" и вызывает некую процедуру. То получается что можно в конце евента добавить вызов этой процедуры.
Или вы хотите чтобы не запускался новый инстанс евента_X, если текущий инстанс евента_X еще не выполнился?
есть такой запрос, который удаляет из таблици объявы у которых "дата истекла". В какой файл вставить это все. и как он будет запускаться сам?
это надо выполнить в mysql
этим будет заниматься mysqld
я так понял вставляем это в msql и все?
да
Я вставил, оно теперь будет само запускаться, где можно посмотреть что оно работает?
В статье написано
Событие не работает,почему INTERVAL_VALUE, INTERVAL_FIELD, STARTS, ENDS у меня NULL?
Оставьте свой комментарий