【问题标题】:MYSQL event on every 1 minute not working每1分钟一次的MYSQL事件不起作用
【发布时间】:2016-12-21 13:41:31
【问题描述】:

首先,这是 OpenCart

我有两张桌子:

1. oc_product(product_id、model、price、event_start、event_end等)
2. oc_product_to_category(product_id, category_id)

每个产品都有开始日期和结束日期。我创建了 MYSQL 事件,该事件捕获所有具有过期日期的产品 (event_end

这是MYSQL EVENT的代码

CREATE EVENT move_to_archive_category
ON SCHEDULE EVERY 1 MINUTE
STARTS NOW()
DO
INSERT INTO `oc_product_to_category` (product_id, category_id) 
SELECT product_id, 68 as category_id 
FROM oc_product p WHERE p.event_end < NOW() AND p.event_end <> '0000-00-00';

当活动开始时,它会正常工作!但是,当我开始管理并发布过期日期的新产品时,我正在等待 1 分钟才能在“存档”类别中看到该产品,但没有任何反应。

我在“SHOW PROCESSLIST”中看到了,一切正常:

event_scheduler     localhost   NULL    Daemon  67  Waiting for next activation     NULL

而且“SHOW EVENTS”看起来也不错

Db  Name    Definer     Time zone   Type    Execute at  Interval value  Interval field  Starts  Ends    Status  Originator  character_set_client    collation_connection    Database Collation
events  move_to_archive_category    root@localhost  SYSTEM  RECURRING   NULL    1   MINUTE  2016-08-15 13:37:54     NULL    ENABLED     1   utf8    utf8_general_ci     utf8_general_ci

我在本地工作,而不是现场

有什么想法吗?

提前致谢! :)

【问题讨论】:

  • 确保oc_product 表中的数据符合归档条件。
  • 是的,我创建了新产品,并使用 end_date = 14.08.2016(今天是 15.08)发布了它,一分钟后(下一个事件激活)在第一次归档后没有任何内容被归档。
  • 可能所有数据(符合条件的)都已在您的第一次运行中存档。 oc_product 表中可能有新数据,但尚未满足条件。可以转储oc_prdouct 表中应该存档但尚未完成的数据吗?
  • 该事件不应该同时删除待归档产品的任何现有oc_product_to_category记录吗?否则,产品可能仍会“附加”到另一个类别。
  • @Pieter 这只是一个新记录。无论产品是否附加到另一个类别。如果产品已过期,它将附加到“存档”(id 68)类别

标签: mysql mysql-event


【解决方案1】:

我建议打开声纳。我的个人资料页面上有 3 个活动链接。因此,我创建了一些辅助表(也可以在这些链接中看到)来帮助打开声纳以查看您的事件中发生了什么。请注意,您可以像我在这些链接中所做的那样扩展它以进行性能跟踪。

请记住,事件的成功或失败(在您的脑海中)取决于数据,并且它们会默默地这样做。但是跟踪正在发生的事情,您可以在其中发展时大大提高您的幸福感。

事件:

DROP EVENT IF EXISTS move_to_archive_category;
DELIMITER $$
CREATE EVENT move_to_archive_category
  ON SCHEDULE EVERY 1 MINUTE STARTS '2015-09-01 00:00:00'
  ON COMPLETION PRESERVE
DO
BEGIN
    DECLARE incarnationId int default 0;
    DECLARE evtAlias varchar(20);

    SET evtAlias:='move_2_archive';
    INSERT incarnations(usedBy) VALUES (evtAlias);
    SELECT LAST_INSERT_ID() INTO incarnationId; 

    INSERT EvtsLog(incarnationId,evtName,step,debugMsg,dtWhenLogged)
    SELECT incarnationId,evtAlias,1,'Event Fired, begin looking',now();

    INSERT INTO `oc_product_to_category` (product_id, category_id) 
    SELECT product_id, 68 as category_id 
    FROM oc_product p WHERE p.event_end < NOW() AND p.event_end <> '0000-00-00';

    -- perhaps collect metrics for above insert and use that in debugMsg below
    -- perhaps with a CONCAT into a msg
    INSERT EvtsLog(incarnationId,evtName,step,debugMsg,dtWhenLogged)
    SELECT incarnationId,evtAlias,10,'INSERT finished',now();

    -- pretend there is more stuff
    -- ... 
    -- ... 

    INSERT EvtsLog(incarnationId,evtName,step,debugMsg,dtWhenLogged)
    SELECT incarnationId,evtAlias,99,'Event Finished',now();

END $$
DELIMITER ;

表格:

create table oc_product_to_category
(   product_id INT not null,
    category_id INT not null
);

create table oc_product
(   product_id INT not null,
    event_end datetime not null
);

drop table if exists incarnations;
create table incarnations
(   -- NoteA
    -- a control table used to feed incarnation id's to events that want performance reporting.
    -- The long an short of it, insert a row here merely to acquire an auto_increment id
    id int auto_increment primary key,
    usedBy varchar(50) not null
    -- could use other columns perhaps, like how used or a datetime
    -- but mainly it feeds back an auto_increment
    -- the usedBy column is like a dummy column just to be fed a last_insert_id()
    -- but the insert has to insert something, so we use usedBy
);

drop table if exists EvtsLog;
create table EvtsLog
(   id int auto_increment primary key,
    incarnationId int not null, -- See NoteA (above)
    evtName varchar(20) not null,   -- allows for use of this table by multiple events
    step int not null,  -- facilitates reporting on event level performance
    debugMsg varchar(1000) not null,
    dtWhenLogged datetime not null
    -- tweak this with whatever indexes your can bear to have
    -- run maintenance on this table to rid it of unwanted rows periodically
    -- as it impacts performance. So, dog the rows out to an archive table or whatever.
);

开启事件:

show variables where variable_name='event_scheduler'; -- OFF currently
SET GLOBAL event_scheduler = ON; -- turn her on
SHOW EVENTS in so_gibberish; -- confirm

确认 Evt 正在触发:

SELECT * FROM EvtsLog WHERE step=1 ORDER BY id DESC; -- verify with our sonar

有关这些辅助表的更多详细信息,请访问我的活动资料页面上的这些链接。几乎只是绩效跟踪和报告的一个链接。

您还会注意到,在您最初关注的实际表中有任何数据时,这无关紧要。这可以稍后出现,并且可以通过将自定义字符串 CONCAT 放入字符串变量(用于计数等)在 evt 日志表中进行报告。并在第 10 步或第 20 步等步骤中报告。

关键是,你完全失明,不知道发生了什么。

【讨论】:

  • 很好解释。某些插入语句中可能缺少INTO
  • 我在 mysql.log 中看到了以下内容 160816 9:58:00 [ERROR] Event Scheduler: [root@localhost][events.move_to_archive_category] Duplicate entry '29-68' for key 'PRIMARY' 1160816 9:58:00 [Note] Event Scheduler: [root@localhost].[events.move_to_archive_category] event execution failed 这是每 1 分钟重复一次...所以该事件正在运行但不受影响
【解决方案2】:

所以,

我在mysqlog中看到如下错误

160816 10:18:00 [ERROR] Event Scheduler: [root@localhost][events.move_to_archive_category] Duplicate entry '29-68' for key 'PRIMARY'

160816 10:18:00 [Note] Event Scheduler: [root@localhost].[events.move_to_archive_category] event execution failed.

我只是在 SQL INSERT 中添加 INGORE... 所以最终结果是

INSERT IGNORE INTO `oc_product_to_category` (product_id, category_id)

【讨论】:

  • 所以你的事件正在触发。您只是在插入已经存在的数据
  • 好的,这样您就知道您的活动正常运行。
  • 是的,它现在运行正常:)
猜你喜欢
  • 1970-01-01
  • 2015-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-02
  • 1970-01-01
  • 2018-01-17
相关资源
最近更新 更多