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.
Related
I would like to delay deletion of data from the database. I am using MySQL, nest.js. I heard that CRON is what I need. I want to delete the entry in a week. Can you help me with this? CRON is what I need, or i need to use something another?
A cron job (or at in Windows) or a MySQL EVENT can be created to periodically check for something and take action. The resolution is only 1 minute.
If you need a very precise resolution, another technique would be required. For example, if you don't want to show a user something that is more than 1 week old to the second, then simply exclude that from the SELECT. That is add something like this to the WHERE: AND created_date >= NOW() - INTERVAL 7 DAY.
Doing the above gives you the freedom to schedule the actual DELETE for only, say, once a day -- rather than pounding on the database only to usually find nothing to do.
If you do choose to "pound on the database", be aware of the following problem. If one instance of the deleter script is running for a long time (for any of a number of reasons), it might not be finished before the next copy comes along. In some situations these scripts can stumple over each other to the extent of effectively "crashing" the server.
That leads to another solution -- a single script that runs forever. It has a simple loop:
Do the actions needed (deleting old rows)
Sleep 1 -- or 10 or 60 or whatever -- this is to be a "nice guy" and not "pound on the system".
The only tricky part is making sure that starts up after any server restart or crash of the script.
You can configure a cronjob to periodically delete it.
There are several ways to configure a cron job.
You can write a shell script that periodically deletes entities in the db using linux crontab, or you can configure an application that provides cronjobs such as jenkins or airflow.
AWS lambda also provides cronjob.
Using crontab provided by nestjs seems to be the simplest to solve the problem.
See this link
https://docs.nestjs.com/techniques/task-scheduling
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
There is a bug on the Mysql 5.7.14 regarding password hash and has been fixed on version 5.7.19. But the Mysql in the GCP doesn't have any option to do a minor upgrade. So can anyone suggest how to go about this issue?
Version 5.7.25, which includes the fix for this bug, will be in the next maintenance release later this month.
No you cannot do minor upgrades by yourself inCloud SQL becasue it is a fully managed service by Google and all updates and upgrades are done behind the scenes for their customers instances. These updates can be done at any time during the next maintenance cycle. However, you can control the day and time and specify a maintenance window for the instance in question.
When you specify a maintenance window, Cloud SQL will not initiate the updates outside of that window. This way you can specify the window when there is less or no traffic on your applications which help reduce the disruptive side effects of that maintenance. Maintenance usually takes between 1-3 minutes for the new update to be pushed and the instance become available again.
To specify a maintenance window:
1- Go to the project page and select a project.
2- Click an Instance name.
3- On the Cloud SQL Instance details page, click Edit maintenance preferences.
4- Under Configuration options, open Maintenance.
5- Configure the following options:
Preferred window. Set the day and hour range when updates can occur on this instance.
Order of update. Set the order for updating this instance, in relation to updates to other instances. Set timing to Any, Earlier, or Later. Earlier instances receive updates up to a week earlier than later instances within the same location.
read more on it here.
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 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.