How can I cyclically remove entries from my database? - mysql

I have a table used to store some entries with a date, which I put in a "datetime" typed field.
I'd like to automatically move those entries at that time to another table.
The result would be having a table with all the passed entries, and one with the future ones.
I was thinking about using a stored procedure, but I wouldn't know how to trigger them when I want.
Or maybe I need a standalone application always running on my server.
Or maybe I'm just not thinking to the right, banal solution...

MySQL offers events, which are like stored procedures but also run at a particular time or on a particular schedule.
The basic sequence of queries to do what you want is this.
START TRANSACTION;
SET #time := NOW() - INTERVAL 24 HOUR;
INSERT INTO archive_log
SELECT *
FROM live_log
WHERE timestamp <= #time;
DELETE FROM live_log WHERE timestamp <= #time;
COMMIT;
You'll run this as often as you need to. Each time you run it you'll move old records from the live_log table to the archive_log table. The phrase - INTERVAL 24 HOUR governs how old the records must be to move them.
You can run this as a MySQL event. For this to work event scheduling must be on in your MySQL server. Read this. https://dev.mysql.com/doc/refman/5.6/en/events-configuration.html
Here's how you declare this event.
CREATE EVENT `archiver`
ON SCHEDULE EVERY 4 HOUR
STARTS '2015-05-23 15:11:23'
ON COMPLETION PRESERVE DO
BEGIN
START TRANSACTION;
SET #time := NOW() - INTERVAL 24 HOUR;
INSERT INTO archive_log
SELECT *
FROM live_log
WHERE timestamp <= #time;
DELETE FROM live_log WHERE timestamp <= #time;
COMMIT;
END
Notice that the query is embedded in the CREATE EVENT code. Debug the query first, before you put it into the event, because debugging events is hard.

Related

Time-based operation in MySQL

I want to perform a time-based operation in MySQL. If the value in the table is 0 while it is 1, the system will start counting time automatically and the value that is 1 should automatically change to 0 at the end of 30 days.
You can use a view for this. Instead of storing the value, store the timestamp when the timing starts. Then just use logic to calculate how recent the value is:
create view v_mytable as
select t.*,
(value_timestamp < curdate() - interval 30 day) as value_flag
from mytable t;

MySQL Recurring event not executing

I have a recurring event set to execute each 1 minute in MySQL:
BEGIN
DELETE FROM session WHERE `date` < DATE_SUB(NOW(), INTERVAL 1 MINUTE);
END
For some reason, my session entries, such as one with the date parameter of
2019-01-19 18:28:24
are not being deleted, despite the fact that SELECT NOW(); currently returns
2019-01-19 18:44:15
So this is more than a minute after the creation date and proves that timezones aren't the problem. Is my event simply failing to execute or is there a problem with the event itself?
EDIT: Please note that the event is set to execute each minute AND delete session entries that are more than a minute old, not just one or the other. The recurring interval isn't shown above, but I've confirmed that it is 1 minute.
I had to run
SET GLOBAL event_scheduler = on;
in order to fix the issue. I had rebooted my XAMPP local server since the last time I tested this, which is why it suddenly stopped working.

mysql event runs but doesnt execute the query

I used to have an archiving event that used to run once everyday without a problem but then recently when I checked, I found out that my event still runs but the query wasn't executed. So I dropped the old event and recreated it and only changed the name and the execution time but now it says there's something wrong with the syntax when I use a mysql syntax checker but it runs using php the only problem is it executes the 2nd query which is delete instead of the 1st first query which is insert. The event looks like this:
CREATE DEFINER=`ricoj`#`%` EVENT `log_archiving` ON SCHEDULE EVERY 1 DAY STARTS
'2016-06-29 12:00:00' ON COMPLETION PRESERVE ENABLE DO BEGIN
insert into archives
select * from app_log where date_sub(curdate( ) , interval 75 DAY) >= created_datetime;
delete from app_log where date_sub(curdate( ) , interval 75 DAY) >= created_datetime;
END

Stored procedure defined by time

I'm fairly new in programming. Everything went smooth so far, but I can't solve this. I'm using MySQL Workbench 5.2.42
I know I need to create a stored procedure
This procedure needs to delete all data in my database, but only if the data I over 15 minutes old. I can access the time from my timestamp at the ExpectedEnd column. But I don't know how to do this right.
CREATE PROCEDURE p_DeleteOldData()
BEGIN
IF ExpectedEnd IS TIMESTAMP + 15
DELETE * tables FROM (DelayedLoading, Loading, LoadingDock, LoadingError, Orders, PartOrders, Semi, Trailer, Truck, Weighing)
End ;
I made this though its surely completely wrong.
edit*
I tried this, but i still can't figure how to get it to the 15 minute mark and delete.
CREATE PROCEDURE p_DeleteOldData(IN theTime DATETIME)
BEGIN
DELETE FROM Loading WHERE ExpectedEnd < theTime;
END;
Thank you in advance.
CREATE PROCEDURE p_DeleteOldData(IN theTime DATETIME)
BEGIN
DELETE FROM Loading WHERE ExpectedEnd < DATE_ADD(theTime, INTERVAL -15 MINUTE);
END;
You can see other interval values in the docs (e.g. HOUR, DAY, WEEK, MONTH) and you can even just use NOW() instead of having to pass a time value into the stored procedure if you are only looking at the current point in time

How to delete a MySQL record after a certain time

I want to delete some messages from my MySQL database after 7 days.
My message table rows have this format:
id | message | date
The date is a timestamp in the normal format; 2012-12-29 17:14:53
I was thinking that an MySQL event would be the way to go instead of a cron job.
I have what I guess is a simple question to an experienced SQL person, how do I code the delete messages portion in brackets below?
An example would be appreciated, Thanks.
DELIMITER $$
CREATE EVENT delete_event
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY
ON COMPLETION PRESERVE
DO
BEGIN
DELETE messages WHERE date >= (the current date - 7 days);
END;
$$;
You can try using this condition:
WHERE date < DATE_SUB(NOW(), INTERVAL 7 DAY)
So that the whole SQL script looks like this:
CREATE EVENT delete_event
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY
ON COMPLETION PRESERVE
DO BEGIN
DELETE messages WHERE date < DATE_SUB(NOW(), INTERVAL 7 DAY);
END;
However, on your place I would solve the given problem with a simple cron script. The reasons to do this is simple: it's easier to maintain the code, no ugly SQL workarounds, integrates smoothly with your system.
This should do the trick.
DELETE FROM messages WHERE date < (CURDATE() - INTERVAL 7 DAY);
For those out there who are on a shared hosting, like 1and1's, and can't create events, an alternative is to use webcron
You just need to tell webcron the url of the php script you'd like to be run, and they'll trigger it for you at the intervals you want