Событие MySQL не запускается
Вопрос
Я бегаю mysql 5.1.41
что шло в комплекте xampp
на окнах.проблема в том, что событие не запускается автоматически, даже если event scheduler
является ON
.у меня есть таблица с именем ta_table
с использованием innodb engine
и он имеет 4 поля, одно из которых ti_time
с timestamp
тип со значением по умолчанию current timestamp
.это поле ti_time
присваивается значение временной метки, в которую вставляется строка.теперь я хочу удалить из таблицы все строки возрастом 2 часа ta_table
Итак, я создал событие, которое событие выглядит так
CREATE EVENT ev ON SCHEDULE EVERY 1 MINUTE STARTS 2011-07-17 14:54:52 ENABLE
DO
begin
delete from ta_table where timestampdiff(minute,ti_time,now())>120;
end
теперь это событие должно удалить все строки с ti_time
поле более 2 часов (120 минут).когда я выполняю этот запрос
delete from ta_table where timestampdiff(minute,ti_time,now())>120;
оно работает.он удаляет строки старше 2 часов.это означает, что мой запрос верен, но событие не запускается.мой планировщик событий работает, что я подтвердил show processlist
и он показывает 2 корневых процесса и планировщик событий.тот state
планировщика событий waiting for next activation
.когда я выполнил этот запрос
SELECT * FROM INFORMATION_SCHEMA.EVENTS WHERE event_name = 'ev'
это дает результат как
status = enabled
last executed=2011-07-18 02:36:38
но когда я вижу стол ta_table
записи не удаляются?что в этом плохого?
Редактировать:
По предложению RolandoMySQLDBA я обновил mysql 5.1.14 до mysql 5.5, но событие по-прежнему не выполняется.
Решение
Я немного покопался в списке ошибок, связанных с проблемами планировщика событий.
Похоже, что определенный расчет времени для планировщика событий не был переносимым.Эта ошибка была исправлена в MySQL 5.1.48 (исправлено 2 июня 2010 г.).
В прошлом возникла проблема, связанная с тем, что SHOW EVENTS не получала события из правильной базы данных..Эта ошибка была исправлена в MySQL 5.1.57 (исправлено 5 мая 2011 г.).
Последняя ошибка планировщика была исправлена 5 июля 2011 г. в MySQL 5.1.58.
Вы используете MySQL 5.1.41. Возможно, вы захотите обновить MySQL до последней версии 5.1 — 5.1.58..На сегодняшний день ошибок в планировщике не существует.
ПРЕДОСТЕРЕЖЕНИЕ
С другой стороны, я бы изменил SQL-запрос, чтобы он не только выполнял меньше работы.
Вместо запроса DELETE:
delete from ta_table where timestampdiff(minute,ti_time,now())>120;
Реструктурируйте его следующим образом:
delete from ta_table where ti_time < (now() - interval 2 hour);
Ваш DELETE будет рассчитываться для каждой строки таблицы.Этот новый DELETE останавливается при сравнении ti_time со значением времени (now() - интервал 2 часа) вместо вычисления timestampdiff для каждой строки.
Убедитесь, что ti_time проиндексировано.Если нет, сделайте следующее:
ALTER TABLE ta_table ADD INDEX (ti_time);
Предполагая, что это таблица MyISAM, вы также можете периодически сжимать таблицу каждый месяц следующим образом:
ALTER TABLE ta_table ENGINE=MyISAM;
Я надеюсь, что эта информация поможет !!!
ОБНОВЛЕНИЕ 19 июля 2011 г., 8:00 по восточному поясному времени.
Вот пример из последнего сеанса чата, который я провел с Лавешем, чтобы создать событие на своем компьютере с MySQL 5.5.12:
drop database lovesh;
create database lovesh;
use lovesh
create table mydata (id int not null auto_increment primary key,ti_time timestamp DEFAULT current_timestamp) ENGINE=MyISAM;
DELIMITER $$
DROP PROCEDURE IF EXISTS `lovesh`.`LoadMyData` $$
CREATE PROCEDURE `lovesh`.`LoadMyData` ()
BEGIN
DECLARE NDX INT;
SET NDX = 0;
WHILE NDX < 100 DO
INSERT INTO mydata (ti_time) VALUES (NOW() - INTERVAL CEILING(14400*RAND()) SECOND);
SET NDX = NDX + 1;
END WHILE;
END $$
DELIMITER ;
show create table mydata\G
SHOW CREATE PROCEDURE LoadMyData\G
CALL lovesh.LoadMyData();
CREATE TABLE ta_table LIKE mydata;
ALTER TABLE ta_table DISABLE KEYS;
INSERT INTO ta_table SELECT SQL_NO_CACHE * FROM mydata;
ALTER TABLE ta_table ENABLE KEYS;
CREATE EVENT ev
ON SCHEDULE
EVERY 1 MINUTE
STARTS (NOW() + INTERVAL 1 MINUTE)
DO
DELETE FROM ta_table WHERE ti_time > NOW() - INTERVAL 2 HOUR;
SELECT COUNT(1) FROM ta_table;
SELECT SLEEP(62);
SELECT COUNT(1) FROM ta_table;
У меня это сработало, когда ta_table был MyISAM.Он просто продолжал работать, используя InnoDB.Это может быть камнем преткновения.
Другие советы
Я считаю, что ваше событие должно быть определена с использованием полностью квалифицированной схемы и таблицы:
В MySQL 5.1.6 любая таблица, упомянутая в заявлении действия события, должна быть полностью квалифицирована с именем схемы, в которой она происходит (то есть как Schema_Name.table_Name).
Ссылка: http://www.cs.duke.edu/csl/docs/mysql-refman/events.html#events-limitations-restrictions
Таким образом, ваш запрос в случае должен быть пересмотрен (с помощью улучшенного запроса Delete Rolando):
DELETE FROM `ta_db`.`ta_table` WHERE ti_time < (NOW() - INTERVAL 2 HOUR);