sql >> データベース >  >> RDS >> Mysql

MySQLにスケジュールされたイベントをログに記録させるにはどうすればよいですか?

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

    スローしたい数の個別のイベント(たとえば、個別にコーディングした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 [email protected];
    
                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 [email protected];
            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を含むログテーブルに対してパフォーマンスレポートを取得します。 、evtNamestep 、および日時。以下のクエリは、複数行のイベント情報を、時間差を付けて、イベントの実行ごとに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 |
    +---------------+---------------------+---------------------+---------+
    

    マイクロ秒単位のより正確なレポートを作成するには、MySQL5.6.4以降が必要です。この回答 をご覧ください 。

    イベントにはUXが関連付けられていないため、イベントを作成するのは難しいです。ロギングテーブルを使用することで、パフォーマンスレポートを作成できるだけでなく、開発中にメッセージをデバッグすることで洞察を得ることができます。

    ログテーブルのサイズを制御できるように、ログテーブルを整理することを忘れないでください。おそらくどこかでアーカイブします(おそらく別のイベントを介して!)。



    1. MySQLでの行から列への変換

    2. MySQLのアクセントに依存しない検索クエリ

    3. 文字列の大文字を数える

    4. SQLでストアドプロシージャを作成するにはどうすればよいですか?