MySQL script with event scheduler before spring boot app starts - mysql

In my app I creating tables with Hibernate annotations, but after this I want to create mysql script to generate raports:
In my resources folder I created data.sql :
DROP EVENT IF EXISTS daily_report;
DELIMITER $$
CREATE EVENT daily_report
ON SCHEDULE EVERY 1 DAY STARTS '2018-01-01'
ON COMPLETION PRESERVE
DO BEGIN
INSERT INTO daily_report(day_of_report,http_errors,other_errors) VALUES(
current_date(),
(select count(*) from error where date(save_date)=current_date() and name="HttpError"),
(select count(*) from error where date(save_date)=current_date() and name not in("unknown","HttpError")
));
END $$
DELIMITER ;
SET GLOBAL event_scheduler = ON;
All looks good, because when I run:
SELECT ##global.event_scheduler;
It shows that is ON, but after running:
show events
It shows no events :(
data.sql script is working because when I run him directly in mysql it works - command show events showing that this daily_report scheduled event is working.

Related

How to write stored procedures in Wampserver to run Automatically

I didn't know anything about Stored procedures. unfortunately I have to run a stored procedure automatically.
I have a table called pass and I want to update status as cancelled at the end of the day automatically. I'm using phpmyadmin in wampserver.
I have already tried some codes but I don't know this code is correct and how to set execution automatically.
here is my code,
CREATE PROCEDURE MyTask
AS
BEGIN
SET NOCOUNT ON;
SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
GO
-- For executing the stored procedure at 1:00 A.M
declare #delayTime nvarchar(50)
set #delayTime = '01:00'
while 1 = 1
BEGIN
waitfor time #delayTime
BEGIN
ALTER PROCEDURE [dbo].[updateDuration] AS
UPDATE pass SET status = 'Cancelled' WHERE duration_type='Daily' && duration = DATE_SUB(CURRENT_DATE(),INTERVAL 1 DAY);
--Name for the stored proceduce you want to call on regular bases
execute [gatepass].[dbo].[updateDuration];
END
END
END
It says that to put below code, but I don't know where to put these.
-- Sets stored procedure for automatic execution.
sp_procoption #ProcName = 'MyTask',
#OptionName = 'startup',
#OptionValue = 'on'
Method #1 - Batching
Create a script named runMyTask.sql or whatever you want.
That script should have your SQL to run the stored procedure:
-- Sets stored procedure for automatic execution.
CALL sp_procoption('MyTask','startup', 'on');
Then you need a batch script which you might name runMyTask.bat.
In the .bat file you add the line that runs the mysql.exe command line tool and redirects the contents of the runMyTask.sql file along the lines of something like
C:/wamp/bin/mysql/mysql..../bin/mysql -u root --password=your_password database_name < C:/path/to/runMyTask.sql
When you have tested that the batch script runs correctly from the windows cmd shell, set it up in the scheduler.
Method #2 MySQL - Event Scheduler
To use the event scheduler you'll need to first make sure you it's enabled on the server. By default it is not. From the aforementioned mysql command line, login as root.
SET GLOBAL event_scheduler = ON;
After you turn it on, run a SHOW PROCESSLIST; command and you should see a line similar to this one, showing the user event_scheduler owning a process.
| 10729276 | event_scheduler | localhost | NULL | Daemon | 4 | Waiting on empty queue | NULL | 0.000 |
At this point you can add "events". To add your stored procedure run as an event, once an hour:
USE your_db;
CREATE EVENT IF NOT EXISTS EventRunMyTask
ON SCHEDULE EVERY 1 HOUR
ENABLE
DO CALL sp_procoption('MyTask','startup', 'on');
If everything goes well you should be able to see information about the scheduled job using SHOW EVENTS;

MySql Schedule event

I want to insert data in a table at the beginning of every month, I though to use mysql event. But someone told me that if I miss that event (Mean if my server is down in scheduled date/time then mysql will no rerun that event after getting online, not sure) then mysql will not rerun it again.
So I have created a table celled event_balance where event will be logged. Then I created a event called balance_update_check which will run every hour and check if event was executed for this month, if not then it will call a procedure which will create rows for this month and then update table event_balance with event_type and date.
But I am not satisfied with this, please check my codes and tell me is it OK? if possible provide a better solution. Thanks for you time.
Event balance_update_check
CREATE
EVENT `balance_update_check`
ON SCHEDULE EVERY 1 Hour
DO BEGIN
set #check_if_cont_doc:= (SELECT count(*) FROM event_balance WHERE event_type = 'doctor_contract' and monthname(event_balance.date) = monthname(CURDATE()));
set #check_if_cont_other:= (SELECT count(*) FROM event_balance WHERE event_type = 'other_contract' and monthname(event_balance.date) = monthname(CURDATE()));
IF (#check_if_cont_doc = 0) Then
call proc_leave_bal_doc_cont();
Insert into event_balance (event_type,`date`) values('doctor_contract',CURDATE())
END IF;
IF (#check_if_cont_other = 0) Then
call proc_leave_bal_other_cont();
Insert into event_balance (event_type,`date`) values('other_contract',CURDATE())
END IF;
END //
You want to make sure that the event_scheduler is set to ON in your my.cnf file. Head over to your my.cnf file (or my.ini file if you are using Windows) and either comment out the event_scheduler=DISABLED or set event_scheduler=ON. Then restart. This is make sure that your events run after a server reboot. There is some more info about it here:dev.mysql.com/doc/refman/5.5/en/events-configuration.html

MySQL event is not running after an interval

I have created an event in MySQL using this query:
delimiter $$
create event update_usability_score
on schedule every 1 day
starts '2013-01-07 18:22:00'
do
begin
insert into table_name(pk_id,name) values(1,"testing");
update table table_name set name = 'Not testing' where name like '%testing%';
end//
delimiter ;
When I run this for 1st time it's working fine and not showing any error. As I queried this event will run every day. But it is not running everyday.
When I check with this:
select name, last_executed from mysql.event;
it is showing the start date. Means it is not running everyday.
How to run this event everyday? Anything I have missed in the query?
Please help to solve this problem, thanks in advance.
You need to set ON COMPLETION PRESERVE option:
CREATE EVENT update_usability_score
ON SCHEDULE EVERY 1 DAY
STARTS '2013-01-07 18:22:00'
ON COMPLETION PRESERVE
DO
BEGIN
...
END
From the event documentation:
Normally, once an event has expired, it is immediately dropped. You can override this behavior by specifying ON COMPLETION PRESERVE. Using ON COMPLETION NOT PRESERVE merely makes the default nonpersistent behavior explicit.
This particular event would fail because the very first query in the event would fail if you would run it second time as id 1 would be already in the database.

Debugging MySQL Triggers

I love triggers for one reason - they just work. I hate triggers for one reason - when they don't work, forget about trying to debug. O the sweet frustration.
Basically, I want to see THE update, delete, insert, etc query that was ran. I want to see that query ... somewhere, in my terminal or a log, exactly how and when MySQL executes it, and possibly any corresponding output/errors. Thoughts/hacks?
I'm trying to debug an update query with a few joins and what not. My queries are much more complex but for brevity here's an example.
DELIMITER |
CREATE TRIGGER ireallyhateyourightnow AFTER UPDATE ON watch_this_table
FOR EACH ROW BEGIN
IF (OLD.my_value != NEW.my_value) THEN
update
my_table
set
my_column = NEW.my_value;
END IF;
END|
DELIMITER ;
Here is some additional context that may help influence a suggestion or answer. Again, I'm less interested in semantics/syntax and more interested in seeing MySQL run the query but by all means, I'm open to anything at this point.
Strace does not work/show query.
Non-replicated environment BUT if the bin logs show trigger statements I will certainly set this up.
Does "show full processlist" show trigger execution and/or statements executed within (I never see them after running show full processlist as fast as perl can run it but I might just be missing it)?
General query log does not show these queries (certainly not the error log).
I'm not using aliases (anymore).
No syntax errors when creating the trigger.
The IF statement works.
When I insert the NEW values into a "test/temp" table and manually run the update query it works (I've even went so far as to actually inserting the whole update query)
I can't show you the query but as I just mentioned, it works when I run manually if that helps.
I've removed all erroneous characters, tabs, carriage returns, newlines, etc.
The MySQL socket would only show local connection/data but not MySQL internal workings, I think.
MyISAM so INNODB logs aren't an option
lsof didn't seem to show anything else to be of use.
I'm using MySQL 5.0.77 on CentOS 5.5.
There's an alternate way of testing it by having a temporary debug table. In the example here, they create it in an own debug database.
Step 1: Create a table
DROP TABLE IF EXISTS debug;
CREATE TABLE debug (
proc_id varchar(100) default NULL,
debug_output text,
line_id int(11) NOT NULL auto_increment,
PRIMARY KEY (line_id)
)
Step 2: Create debug SPs to fill the debug table
DELIMITER $$
DROP PROCEDURE IF EXISTS `debug_insert` $$
CREATE PROCEDURE `debug_insert`(in p_proc_id varchar(100),in p_debug_info text)
begin
insert into debug (proc_id,debug_output)
values (p_proc_id,p_debug_info);
end $$
DROP PROCEDURE IF EXISTS `debug_on` $$
CREATE PROCEDURE `debug_on`(in p_proc_id varchar(100))
begin
call debug_insert(p_proc_id,concat('Debug Started :',now()));
end $$
DROP PROCEDURE IF EXISTS `debug_off` $$
CREATE PROCEDURE `debug_off`(in p_proc_id varchar(100))
begin
call debug_insert(p_proc_id,concat('Debug Ended :',now()));
select debug_output from debug where proc_id = p_proc_id order by line_id;
delete from debug where proc_id = p_proc_id;
end $$
Step 3: Invoke the debug SPs in your trigger
Like this,
CREATE PROCEDURE test_debug()
begin
declare l_proc_id varchar(100) default 'test_debug';
call debug_on(l_proc_id);
call debug_insert(l_proc_id,'Testing Debug');
call debug_off(l_proc_id);
end $$
As a result the debug table would be filled as follows,
+------------------------------------+
| debug_output |
+------------------------------------+
| Debug Started :2006-03-24 16:10:33 |
| Testing Debug |
| Debug Ended :2006-03-24 16:10:33 |
+------------------------------------+
You can debug triggers using dbForge Studio for MySQL. Try trial version.
There is a detailed description of the trigger debugging process in the documentation: Debugging \ Debugging Stored Routines \ How To: Start Trigger Debugging.
MYSQL PROCEDURE => incron => tail -f 'mysql_dynamic.log'
A Stored Procedure can be invoked inside a trigger but must return nothing
CREATE PROCEDURE `DYN_LOG` (IN s VARCHAR(500))
BEGIN
SELECT s into outfile '/var/spool/incron/mysql_dynamic_spool/foo_file';
DO SLEEP(.1); // create a gap beetween multiple shuts
END
Now anywhere in a trigger you can invoke
CREATE TRIGGER `trig_name` BEFORE UPDATE ON `tb_name`
FOR EACH ROW
BEGIN
CALL DYN_LOG(concat_ws('\t',NEW.col1,NEW.col2));
...
// rest of the code
END
for Linux machines apt-get install incron (debian incron tutorial)
Create the folder in which mysql will inject foo_file
mkdir -m 777 /var/spool/incron/mysql_dynamic_spool
incrontab -e
and add following incron job
/var/spool/incron/mysql_dynamic_spool IN_CREATE /path/foo_file_procesor $#/$#
Create executable script "/path/foo_file_procesor"
#!/bin/sh
# // $1 is the foo_file absolute addres
body="$(cat $1)" #// read file content
rm $1
log=/var/log/mysql_dynamic.log #// message collector
echo "`date "+%Y-%m-%d %H:%M:%S"`\t== dyn_log ==\t$body">>$log
exit 0
Now watch the collector file
tail -f /var/log/mysql_dynamic.log

How to schedule a stored procedure in MySQL

I have this stored procedure. How can I run this for example with intervals of 5 seconds? Like a routine for eliminate data with a time-stamp older than one day?
DROP PROCEDURE IF EXISTS `delete_rows_links`
GO
CREATE PROCEDURE delete_rows_links
BEGIN
DELETE activation_link
FROM activation_link_password_reset
WHERE TIMESTAMPDIFF(DAY, `time`, NOW()) < 1 ;
END
GO
You can use mysql scheduler to run it each 5 seconds. You can find samples at http://dev.mysql.com/doc/refman/5.1/en/create-event.html
Never used it but I hope this would work:
CREATE EVENT myevent
ON SCHEDULE EVERY 5 SECOND
DO
CALL delete_rows_links();
I used this query and it worked for me:
CREATE EVENT `exec`
ON SCHEDULE EVERY 5 SECOND
STARTS '2013-02-10 00:00:00'
ENDS '2015-02-28 00:00:00'
ON COMPLETION NOT PRESERVE ENABLE
DO
call delete_rows_links();
In order to create a cronjob, follow these steps:
run this command : SET GLOBAL event_scheduler = ON;
If ERROR 1229 (HY000): Variable 'event_scheduler' is a GLOBAL
variable and should be set with SET GLOBAL:
mportant
It is possible to set the Event Scheduler to DISABLED only at server startup. If event_scheduler is ON or OFF, you cannot set it to DISABLED at runtime. Also, if the Event Scheduler is set to DISABLED at startup, you cannot change the value of event_scheduler at runtime.
To disable the event scheduler, use one of the following two methods:
As a command-line option when starting the server:
--event-scheduler=DISABLED
In the server configuration file (my.cnf, or my.ini on Windows systems):
include the line where it will be read by the server (for example, in a [mysqld] section):
event_scheduler=DISABLED
Read MySQL documentation for more information.
DROP EVENT IF EXISTS EVENT_NAME;
CREATE EVENT EVENT_NAME
ON SCHEDULE EVERY 10 SECOND/minute/hour
DO
CALL PROCEDURE_NAME();
If you're open to out-of-the-DB solution: You could set up a cron job that runs a script that will itself call the procedure.