3

First, this is OpenCart

I have two tables:

1. oc_product (product_id, model, price, event_start, event_end and etc.)
2. oc_product_to_category (product_id, category_id)

Every product has Start Date and End Date. I created MYSQL event that catch every product with expired date (event_end < NOW()) to store it in category "Archive" with id = 68

Here is the code of 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';

When event starts it works properly! BUT, when I got to administration and publish new product with expired date I'm waiting 1 minute to see the product in "Archive" category but nothing happens.

I saw in "SHOW PROCESSLIST" and everything is OK:

event_scheduler     localhost   NULL    Daemon  67  Waiting for next activation     NULL

and also "SHOW EVENTS" looks good

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

I'm working locally, not live

Any ideas?

Thanks in advance! :)

tweb
  • 123
  • 3
  • 12
  • Ensure you have data in `oc_product` table meeting the criteria of being archived. – 1000111 Aug 15 '16 at 11:19
  • Yes, I created new product and I published it with end_date = 14.08.2016 (today is 15.08) and after a minute (next event activation) nothing is archived after first archivation. – tweb Aug 15 '16 at 11:25
  • May be all data(which meeting the criteria) have been archived in your first run. You might have new data in `oc_product` table but it's yet to meet the criteria. Can you dump the data from `oc_prdouct` table which are supposed to be archived but not yet done? – 1000111 Aug 15 '16 at 11:27
  • Shouldn't the event also delete any existing `oc_product_to_category` records of the to-be archived product? Otherwise the product might still be 'attached' to another category. – Pieter Aug 15 '16 at 11:42
  • @Pieter it's just a new record. No matter if the product is attached to another category. If product is expired date it will be attached to "archive" (id 68) category – tweb Aug 15 '16 at 13:23

2 Answers2

2

I suggest turning on the sonar. I have 3 event links hanging off my profile page. So I created a few helper tables (that can also be seen in those links) to assist is turning on the sonar to see what is up in your events. Note you can expand on it for performance tracking as I did in those links.

Remember that Events succeed or fail (in your mind) based on the data and they do so silently. But tracking what is going on, you can vastly increase you happiness level when developing in them.

Event:

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 ;

Tables:

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.
);

Turn on Events:

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

Confirm Evt is firing:

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

enter image description here

For more details of those helper tables, visit those links off my profile page for Events. Pretty much just the one link for Performance Tracking and Reporting.

You will also note that it is of no concern at the moment of having any data in the actual tables that you were originally focusing on. That can come later, and can be reported on in the evt log table by doing a custom string CONCAT into a string variable (for the counts etc). And reporting that in a step # like step 10 or 20.

The point is, you are completely blind without something like this as to know what is going on.

Drew
  • 24,851
  • 10
  • 43
  • 78
  • Well explained. May be `INTO` missing in some of the insert statements – 1000111 Aug 15 '16 at 14:52
  • I saw in mysql.log the following things `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` This is repeat on every 1 minute... so the event is working but not affected – tweb Aug 16 '16 at 07:03
0

So,

I saw in mysqlog the following errors

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.

and I just add INGORE in SQL INSERT... so the finally result is

INSERT IGNORE INTO `oc_product_to_category` (product_id, category_id)
tweb
  • 123
  • 3
  • 12