windowsでxampp
にバンドルされているmysql 5.1.41
を実行しています。問題は、event scheduler
がON
であっても、イベントが自動的に実行されないことです。 ta_table
という名前のテーブルがあり、innodb engine
を使用して4つのフィールドがあり、そのうちの1つは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で修正されました(2010年6月2日で修正)。
SHOW EVENTSが正しいデータベースからイベントを取得しないという過去の問題がありました 。このバグはMySQL 5.1.57(2011年5月5日修正)で修正されています。
最新のスケジューラのバグは、2011年7月5日に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は、すべての行でtimestampdiffを計算する代わりに、ti_timeを時間値(now()-間隔2時間)と比較すると、短時間で停止します。
Ti_timeにインデックスが付けられていることを確認してください。そうでない場合は、次のようにします。
ALTER TABLE ta_table ADD INDEX (ti_time);
テーブルがMyISAMであると仮定すると、次のようにテーブルを毎月定期的に縮小することもできます。
ALTER TABLE ta_table ENGINE=MyISAM;
この情報がお役に立てば幸いです。
UPDATE 2011-07-19 08:00 EDT
最後のチャットルームセッションloveshと私が持っていた、MySQL 5.5.12を実行している私のPCでイベントを作成するために実行した例を次に示します。
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
したがって、EVENT内のクエリを再定義する必要があります(Rolandoの改良された削除クエリを使用):
DELETE FROM `ta_db`.`ta_table` WHERE ti_time < (NOW() - INTERVAL 2 HOUR);