I have a MySQL event scheduled to run everyday at midnight - But the database server is shutdown everyday evening and is restarted every morning, but not necessarily at the same time. For instance the server is started at: 10AM, I still need the event to be executed for the day, though it was scheduled for 12AM. I tested this scenario in ORACLE and it works, but doesn't quite in MySQL. Do you have a suggestion?
Thanks in advance,
Abhilash
Direct support for this behaviour was submitted as a feature request in bug #46813. It is still "awaiting triage":
The event scheduler should be able to periodically check for, and catch up on, missed events. While events that need to run this way can be scheduled using Task Scheduler on Windows and anacron on Mac and *nix, this is inelegant and platform-dependent.
As the bug report suggests, you can schedule such events using software that is external to MySQL. Alternatively, one could use MySQL's init-file option to specify a file containing commands that should be executed on startup; using that one could check the INFORMATION_SCHEMA.EVENTS table: compare LAST_EXECUTED column against event schedule and execute EVENT_DEFINITION if a scheduled event was missed.
Sorry, but MySQL doesn't handle this. If the event is missed, it's missed. It doesn't try to run it again later.
What you could do is make a table that logs when an event was last run (the date), then schedule it for each hour, but before running check if it already ran that day. That way the first time it runs after midnight it will activate.
You can create an event that would fire every hour. Create additional table to store information about event's firing.
Do these steps in the event:
check if event was fired - read info. from the table
do the code if the event stil was not fired, write information (the date) into the table.
Related
I have a MySql 5.6.10 database with the event scheduler enabled.
There are several events that are currently running successfully. I disabled one event and then after enabling it again, i noticed that it wasn't running. I tried disabling and enabling a few times, but still the event was not starting. So, i dropped the event and recreated it. That still didn't work, and the event will not run.
The event calls a stored procedure and I can manually run the CALL proc() that is in the event, and that works.
I created a test table and a test event to insert into that table, and that one doesn't work either.
Here is the test event i created:
CREATE EVENT test_event_01
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 MINUTE
ON COMPLETION PRESERVE
DO
BEGIN
INSERT INTO test_db.test_event_msg(message_text,createdDate)
VALUES('Test MySQL Event 1',UTC_TIMESTAMP());
END
Any thoughts or suggestions that I can try or check?
Thank for any help!
As I wrote in the last comment, rebooting the MySQL instance resolved the issue with the event scheduler.
So i have this database running on a Synology NAS, for a restaurant's app made with Laravel, and i have this event here that should start every day at 4am
The content of this event is nothing special:
UPDATE shipping_times SET shipping_times.available = shipping_times.max_quantity
Thing is, every night at midnight the event scheduler variable auto sets to OFF even if i do GLOBAL event_scheduler = ON.
This is quite a problem since the event is used to "replenish" available orders.
Since my event should occur at 4AM i don't think the problem is event-related.
What could it be?
Alternative: Laravel Task Scheduling
Laravel Tasks come to mind for solving this instead: https://laravel.com/docs/8.x/scheduling
(other Laravel version docs available there as well)
Adding recurring tasks in this way puts them all in one place instead of hidden somewhere in a menu. They are also independant of your elusive event_scheduler.
You can also use a command and call it from the task scheduling code. See BKF's comment.
Are your events firing?
I am not sure but could it be true the event is only firing if you always have traffic between 00:00 and 04:00? Laravel Tasks also fire after the fact, AFAIK.
Add this to my.cnf (or whaterver the config file is):
event_scheduler = ON
and restart mysqld.
Apparently, something is shutting down MySQL every night, perhaps a backup? The above setting will turn it on each time it restarts.
I'm using MySQL 8.0.21 From the MySQL Community Installer on Windows 10 updated to version2004 and for some reason if I create a event in the event scheduler, which calls a procedure once every second (regardless of what that SP actually does, I'll explain my test case) - my CPU maxes out and when I look at the active connections in MySQL Workbench, it stacks up a ton of worker threads which stall on the "Opening Tables" state. My PC freezes, I have to edit the event to be disabled, stop the MySQL process in Task Manager and Start the service again.
TEST CASE
During setup of a brand new server, I used all default settings, except I enabled the general log and I use the new 8.0+ mysql_sha2_password encryption (although I ALTER USER to mysql_native_password for phpmyadmin so that might revert it, I'm honestly not sure)
I create a new Schema called "Test"
I create one Table called
"TestTable" has only one column called "column1" INT
I then create a Stored Procedure "TestProc" which does "SELECT COUNT(*) FROM
TestTable;" Adjusts Priv.'s, DEFINER::Definer is root#localhost and
Reads SQL
And Finally I create an Event called "TestEvent" which does
"CALL TestProc()s" Reoccurring every 1/sec, preserve on Complete, and
definer is root#localhost
restart server before event is fired.
Also, if I enable the event, or create it, it'll run without issue, it's important to note that the issue begins when the event scheduler is left on, and the event is left enabled, then the server is restarted from the services in task manager. Immediately the CPU jacks up to max and active connections show threads stacking up without completing.
Any clues are appreciated, I find no actual errors nor do I have any idea where to begin debugging anymore. I've tried skipping grant tables (but obviously that's not optimal, and didn't work).
I did find a hint when reviewing the MySQL 8.0+ docs
"If a repeating event does not terminate within its scheduling interval, the result may be multiple instances of the event executing simultaneously. If this is undesirable, you should institute a mechanism to prevent simultaneous instances. For example, you could use the GET_LOCK() function, or row or table locking. " from
However, when analyzing there does not appear to be any locks, nor should I need to implement such manually just for this test case (or my actual program)
UPDATE
Up to this point, albeit a rather niche bug, I do believe that is exactly what this is, and I have posted it on MySQL bug forum. Reference post is here:
The answer actually has turned out to be a bug which is reproducible - Bug#: 100449
I have an NP-hard data transformation problem that I know can run for hours. So I'm fine tuning some heuristics to keep the complexity under control.
But the process may take 5 minutes to run with one setting and 10 hours with an adjustment of 20% on just one parameter. As this also depends on the actual data.
I would like to stop the process if it is running for too long. This is both in regular operation as well as when I trigger the event manually.
The idea was to track the show processlist, identify this event and kill it if it's been running over 15 minutes. Unfortunately I don't seem to see any running process from the event - even though I can see log entries written at the same time.
How can I kill a process fired by the event scheduler?
I'm using MySQL 5.7 on CentOS.
I have to develop/use a scheduler in my NodeJS project to check if any subscriptions need to be renewed. Job needs to run once every day and check my database if 'enddate' of a any user subscription record falls on that day. If it is, run a piece of logic to renew it (i have my own renew logic which doesnt depend on any external services like payment providers/gateways).
Application will be in cloud which means all my app instances have to be stateless. Database (MySQL) is the only stateful part of the system and Renew logic has to run only once.
How can i do this ?
My database table row for a subscription looks like this:
Id: 1, User: John Doe, Plan: Monthly Premium, Start Date: 1-10-2015, End Date: 30-10-2014, status : "ACTIVE"
Problems:
1.) Trigger job running logic everyday - Easy to solve in nodejs with setInterval or a scheduler library
2.) Running a worker or a piece of code that checks the db and renews it - This needs to happen only once per user subscription. Many instances can potentially run the renew logic at the same time when daily scheduler triggers the process. Not sure how to solve this part of the problem.
One possible solution consists of a shell script, put in your crontab, that would run each day.
This script would do :
Using a sql statement or stored procedure, find records where subscription
end date is today
For those records, apply your logic. (send email or anything else)
Flag the record to indicate that a something has been done
for this user (and put in another field the process date).
you can create a worker and use node-cron to trigger subscription expire everyday.
i'm not sure what renew process does. you can use lock something until the renew process complete and release it. I was thinking i would use redlock
You can use Agenda, but it requires a MongoDb to maintain its state. If you are okay with adding one more DB, then you can give this a shot.