Как я могу иметь запланированные события журнала MySQL?
Я создал Событие, но не могу понять, как регистрировать, когда он выполняется, сколько времени это занимает и есть ли какие-либо ошибки. Как мне это сделать?
CREATE EVENT ON SCHEDULE EVERY 5 MINUTE
DO BEGIN
...do something...
END
2 ответа
Я использую следующее для отчетов об эффективности событий.
Обратите внимание, что он может обрабатывать столько отдельных событий (например, N событий, которые вы кодируете отдельно), которые вы хотите добавить в него.
То, что вы делаете в качестве шагов внутри вашего мероприятия, зависит от вас. У меня есть ссылка в Событии ниже на не показанную здесь таблицу, а также на то, что я делаю в Событии, которое является обычным для этой единственной компании. Показать все, что сделало бы этот ответ слишком длинным. Если вы программист событий, вы найдете для него применение.
Так же WHILE
цикл в моем событии может быть не лучшим, пока вы не закодируете некоторые простые события без них. Если вы не сможете безопасно выйти из WHILE, ваше мероприятие будет длиться вечно. Так что имейте это в виду, если что-нибудь здесь.
Схема заглушки
Следующая таблица используется событием в верхней части своего кода для вставки в него с единственной целью получения уникального id
назад для использования во вставках в таблицу журнала. Разверните его с помощью столбца даты и времени или тому подобного. Это показывает тривиальное usedBy
столбец, чтобы захватить что-то, по крайней мере, как имя события. Главным образом, он хочет получить от него назначенный auto_increment (id
).
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.
);
Пример события
-- Now the event kicks in on the server on its interval schedule and processes the batch.
-- But we need to modify that Event code because prior all it did was write a row to the log table
-- saying it was looking around. But it didn't actually do anything
drop event if exists `Every_2_Minutes_QuestionUpdateImport`;
DELIMITER $$
CREATE EVENT `Every_2_Minutes_QuestionUpdateImport`
ON SCHEDULE EVERY 2 MINUTE STARTS '2015-09-01 00:00:00'
ON COMPLETION PRESERVE
DO BEGIN
DECLARE bContinue bool default true;
DECLARE counter int default 0;
DECLARE logMsg varchar(1000);
DECLARE incarnationId int default 0;
DECLARE evtAlias varchar(20);
-- right here you could save `now()` into a variable, let's call it STARTEVT
set evtAlias:='ev2minQUI'; -- a shorter unique alias name, max 20 chars
-- Below we must acquire our incarnation id from the control table used for all events
-- that want to use it. It facilitates performance reporting with the use of the `steps` column and the datetime
-- that are put in the EvtsLog table
insert incarnations(usedBy) values (evtAlias); -- see NoteA
select last_insert_id() into incarnationId; -- an auto_increment handed to us by the control table
insert EvtsLog(incarnationId,evtName,step,debugMsg,dtWhenLogged)
select incarnationId,evtAlias,1,'Event Fired, begin looking',now(); -- 1: we are beginning
WHILE bContinue DO -- this is an intermediate-level skills event example. Be careful or you are stuck in the event forever
select min(batchId) into @idToPerform
from EvtsQuestionsToImportBatchHandler -- table not shown in this post on Stackru
where batchStatus=1; -- @idToPerform, a variable, will be null if there is no such row
insert EvtsLog(incarnationId,evtName,step,debugMsg,dtWhenLogged)
select incarnationId,evtAlias,5,'Debug Place 1',now();
IF (@idToPerform IS NOT NULL) THEN
-- This next update line is very crucial, to mark the batch as underway and never picked up again
-- at the top of this WHILE loop (otherwise you may be stuck in here forever)
update EvtsQuestionsToImportBatchHandler set batchStatus=2,dtProcessBegan=now() where batchId=@idToPerform;
set counter:=counter+1; -- used outside of the while loop in the end
insert EvtsLog(incarnationId,evtName,step,debugMsg,dtWhenLogged)
select incarnationId,evtAlias,10,"a message maybe from concat and variables",now();
--
-- Here is where you actually do something
-- Here is where you actually do something
-- Here is where you actually do something
insert EvtsLog(incarnationId,evtName,step,debugMsg,dtWhenLogged)
select incarnationId,evtAlias,20,"a message maybe from concat and variables",now();
-- Here is where you actually do something
-- Here is where you actually do something
-- Here is where you actually do something
insert EvtsLog(incarnationId,evtName,step,debugMsg,dtWhenLogged)
select incarnationId,evtAlias,30,"a message maybe from concat and variables",now();
-- mark this batch as done:
update EvtsQuestionsToImportBatchHandler set batchStatus=3,dtProcessFinished=now() where batchId=@idToPerform;
ELSE
set bContinue=false; -- we are done with the event loop
END IF;
-- if bContinue is true, we will seek the next batch to process that has batchStatus=1, if there is one
-- right here a new now() could be performed, and a timediff() against the STARTEVT
-- to determine if you want to bail out also with a " set bContinue=false; "
END WHILE; -- this is an intermediate-level skills event example. Be careful or you are stuck in the event forever
-- this msg is crucial to see in the log table to know you are not locking in an endless WHILE loop
set logMsg:=concat("Number of batches processed=",counter); -- concat example (could have been used above)
insert EvtsLog(incarnationId,evtName,step,debugMsg,dtWhenLogged)
select incarnationId,evtAlias,90,logMsg,now(); -- 90: we are almost done
insert EvtsLog(incarnationId,evtName,step,debugMsg,dtWhenLogged)
select incarnationId,evtAlias,99,'Event Done',now(); -- 99: we are done
END$$
DELIMITER ; -- sets the delimiter back to what we are used to, the semi-colon
Естественно, вы получаете отчеты о производительности по таблице журналов, которая включает incarnationId
, evtName
, step
и дата и время. Приведенный ниже запрос сворачивает информацию о событиях, состоящих из нескольких строк, в одну строку для каждого запуска события с разницей во времени.
select incarnationId,dtBegin,dtEnd,TIMESTAMPDIFF(SECOND,dtBegin,dtEnd) as secDiff
from
( select incarnationId,min(dtBegin) as dtBegin,max(dtEnd) as dtEnd
from
( select incarnationId,
case
when step=1 then dtWhenLogged
end as dtBegin,
case
when step=99 then dtWhenLogged
end as dtEnd
from evtsLog
where evtName='evtName01'
) d1
group by incarnationId
) d2;
+---------------+---------------------+---------------------+---------+
| incarnationId | dtBegin | dtEnd | secDiff |
+---------------+---------------------+---------------------+---------+
| 101 | 2016-05-01 14:02:00 | 2016-05-01 14:02:01 | 1 |
| 102 | 2016-05-01 14:02:01 | 2016-05-01 14:02:07 | 6 |
+---------------+---------------------+---------------------+---------+
Для более точных отчетов в микросекундах требуется MySQL 5.6.4 или выше. Смотрите этот ответ.
События сложно написать, поскольку с ними не связан UX. Используя таблицу журналов, вы можете не только получать отчеты о производительности, но и получать информацию об отладочных сообщениях во время их разработки.
Не забудьте обрезать таблицу журналов, чтобы держать ее размер под контролем. Возможно, заархивировать его где-нибудь (может быть через другое событие!)