6

Eventを作成しましたが、実行時にログを記録する方法、所要時間、エラーがあるかどうかがわかりません。どうすればいいですか?

CREATE EVENT ON SCHEDULE EVERY 5 MINUTE
DO BEGIN
    ...do something...
END
4

2 に答える 2

11

イベント パフォーマンス レポートには以下を使用します。

スローしたい数の個別のイベント (たとえば、個別にコーディングした N 個のイベント) を処理できることに注意してください。

イベント内でステップとして何をするかはあなた次第です。以下のイベントには、ここに表示されていない表への参照と、この 1 つのビジネスに合わせてイベントで行っていることがあります。すべてを表示すると、この回答が長くなりすぎます。あなたがイベント プログラマーであれば、その用途を見つけることができます。

また、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 Stackoverflow
        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以下のクエリは、複数行のイベント情報をイベント実行ごとに時間差で 1 行にまとめます。

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 がないため、イベントを記述するのは難しいです。ログ テーブルを使用すると、パフォーマンス レポートを作成できるだけでなく、開発中にデバッグ メッセージを使用して洞察を得ることができます。

サイズを制御下に保つために、ログ テーブルを削除することを忘れないでください。どこかにアーカイブするかもしれません (別のイベント経由かもしれません!)。

于 2016-06-24T21:04:59.877 に答える
7
SELECT * FROM INFORMATION_SCHEMA.EVENTS 

が手伝う

于 2016-06-24T13:11:09.483 に答える