Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Làm cách nào tôi có thể có các Sự kiện đã lên lịch trong nhật ký MySQL?

Tôi sử dụng phần sau cho Báo cáo Hiệu suất Sự kiện.

Lưu ý rằng nó có thể xử lý nhiều sự kiện riêng biệt (ví dụ N sự kiện mà bạn viết mã riêng) mà bạn muốn.

Những gì bạn làm với tư cách là Các bước bên trong Sự kiện của bạn là tùy thuộc vào bạn. Tôi có tham chiếu trong Sự kiện bên dưới về một bảng không được hiển thị ở đây cũng như những gì tôi làm trong Sự kiện là tùy chỉnh cho một doanh nghiệp này. Hiển thị tất cả những gì sẽ làm cho câu trả lời này quá dài. Nếu bạn là một lập trình viên Sự kiện, bạn sẽ tìm thấy của bạn sử dụng cho nó.

Ngoài ra, WHILE vòng lặp trong sự kiện của tôi có thể không tốt nhất cho đến khi bạn viết mã một số sự kiện đơn giản mà không có chúng. Nếu bạn không thoát khỏi WHILE một cách an toàn, sự kiện của bạn sẽ diễn ra mãi mãi. Vì vậy, hãy ghi nhớ điều đó nếu có bất cứ điều gì ở đây.

Sơ đồ giản đồ

Bảng sau được Sự kiện gần đầu mã sử dụng để thực hiện chèn vào bảng đó, với mục đích duy nhất là nhận được một id duy nhất quay lại để sử dụng trong phần chèn vào bảng nhật ký. Mở rộng nó bằng cột ngày giờ hoặc tương tự. Nó hiển thị một usedBy tầm thường để nắm bắt một cái gì đó ít nhất, chẳng hạn như tên Sự kiện. Về cơ bản, nó muốn lấy lại auto_increment được chỉ định từ nó (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
);

Dưới đây là bảng ghi nhật ký chung:

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.
);

Một sự kiện mẫu

-- 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

Đương nhiên, bạn nhận được Báo cáo hiệu suất dựa trên bảng nhật ký bao gồm incarnationId , evtName , step và ngày giờ. Truy vấn dưới đây thu gọn thông tin sự kiện nhiều hàng thành 1 hàng cho mỗi lần chạy sự kiện, với thời gian chênh lệch.

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 |
+---------------+---------------------+---------------------+---------+

Để có báo cáo chính xác hơn trong micro giây, cần có MySQL 5.6.4 trở lên. Xem câu trả lời này .

Sự kiện khó viết vì không có UX nào liên quan đến chúng. Bằng cách sử dụng bảng ghi nhật ký, bạn không chỉ có thể đạt được báo cáo hiệu suất mà còn có được thông tin chi tiết với các thông báo gỡ lỗi trong quá trình phát triển chúng.

Đừng quên cắt bớt bảng nhật ký để giữ kích thước của nó trong tầm kiểm soát. Có lẽ đang lưu trữ nó ở đâu đó (có thể thông qua một Sự kiện khác!).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Lỗi MySQL - # 1062 - Mục nhập trùng lặp '' cho khóa 2

  2. Làm cách nào để thoát đầu vào db MySQL trong Python3?

  3. Các câu lệnh SELECT đã sử dụng có một số cột khác nhau

  4. Có bất kỳ triển khai CachedRowSet nào tốt ngoài Sun độc quyền không?

  5. Làm cách nào để đặt mã hóa cho các cột char của bảng trong django?