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

Thu thập dữ liệu tự động về các công việc đã hoàn thành trong MS SQL Server

Giới thiệu

Điều quan trọng là người quản trị cơ sở dữ liệu phải biết những nhiệm vụ nào và chúng đã được hoàn thành như thế nào. Để đơn giản hóa quá trình này, tốt hơn là nên tự động hóa nó, thay vì thực hiện nó theo cách thủ công.

Trong bài viết này, tôi sẽ phân tích một ví dụ cụ thể về cách tự động thu thập dữ liệu về các tác vụ đã hoàn thành của SQL Server Agent.

Giải pháp

Thuật toán:

  1. Tạo một phiên bản để chọn công việc:
    USE [DATABASE_NAME]
    GO
    
    SET ANSI_NULLS ON
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    CREATE view [srv].[vJobRunShortInfo] as
    SELECT sj.[job_id] as Job_GUID
          ,j.name as Job_Name
          ,case sj.[last_run_outcome]
            when 0 then 'Error'
            when 1 then 'Successful'
            when 3 then 'Canceled'
            else case when sj.[last_run_date] is not null and len(sj.[last_run_date])=8 then 'Inconsistent state'
                    else NULL
                    end
           end as LastFinishRunState
          ,sj.[last_run_outcome] as LastRunOutcome
          ,case when sj.[last_run_date] is not null and len(sj.[last_run_date])=8 then
            DATETIMEFROMPARTS(
            substring(cast(sj.[last_run_date] as nvarchar(255)),1,4),
            substring(cast(sj.[last_run_date] as nvarchar(255)),5,2),
            substring(cast(sj.[last_run_date] as nvarchar(255)),7,2),
            case when len(cast(sj.[last_run_time] as nvarchar(255)))>=5 
            then substring(cast(sj.[last_run_time] as nvarchar(255)),1,len(cast(sj.[last_run_time] as nvarchar(255)))-4)
              else 0
              end,
            case when len(right(cast(sj.[last_run_time] as nvarchar(255)),4))>=4 
            then substring(right(cast(sj.[last_run_time] as nvarchar(255)),4),1,2)
            when len(right(cast(sj.[last_run_time] as nvarchar(255)),4))=3  
            then substring(right(cast(sj.[last_run_time] as nvarchar(255)),4),1,1)
               else 0
               end,
            right(cast(sj.[last_run_duration] as nvarchar(255)),2),
                                0
                            )
           else NULL
           end as LastDateTime
           ,case when len(cast(sj.[last_run_duration] as nvarchar(255)))>5 
           then substring(cast(sj.[last_run_duration] as nvarchar(255)),1,len(cast(sj.[last_run_duration] as nvarchar(255)))-4)
                when len(cast(sj.[last_run_duration] as nvarchar(255)))=5 
           then '0'+substring(cast(sj.[last_run_duration] as nvarchar(255)),1,len(cast(sj.[last_run_duration] as nvarchar(255)))-4)
                else '00'
           end
           +':'
           +case when len(cast(sj.[last_run_duration] as nvarchar(255)))>=4 then substring(right(cast(sj.[last_run_duration] as nvarchar(255)),4),1,2)
                 when len(cast(sj.[last_run_duration] as nvarchar(255)))=3  then '0'+substring(right(cast(sj.[last_run_duration] as nvarchar(255)),4),1,1)
                 else '00'
           end
           +':'
           +case when len(cast(sj.[last_run_duration] as nvarchar(255)))>=2
            then substring(right(cast(sj.[last_run_duration] as nvarchar(255)),2),1,2)
                 when len(cast(sj.[last_run_duration] as nvarchar(255)))=2  
            then '0'+substring(right(cast(sj.[last_run_duration] as nvarchar(255)),2),1,1)
                 else '00'
           end as [LastRunDurationString]
          ,sj.last_run_duration as LastRunDurationInt
          ,sj.[last_outcome_message] as LastOutcomeMessage
          ,j.enabled as [Enabled]
      FROM [msdb].[dbo].[sysjobservers] as sj
      inner join msdb.dbo.sysjobs_view as j on j.job_id=sj.job_id;
    
    GO

    Để làm điều này, hãy sử dụng máy chủ hệ thống và phiên bản sysjobs_view.

  2. Tạo bảng để lưu trữ dữ liệu đã chọn:
    USE [DATABASE_NAME]
    GO
    
    SET ANSI_NULLS ON
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    CREATE TABLE [srv].[ShortInfoRunJobs](
        [Job_GUID] [uniqueidentifier] NOT NULL,
        [Job_Name] [nvarchar](255) NOT NULL,
        [LastFinishRunState] [nvarchar](255) NULL,
        [LastDateTime] [datetime] NOT NULL,
        [LastRunDurationString] [nvarchar](255) NULL,
        [LastRunDurationInt] [int] NULL,
        [LastOutcomeMessage] [nvarchar](255) NULL,
        [LastRunOutcome] [tinyint] NOT NULL,
        [Server] [nvarchar](255) NOT NULL,
        [InsertUTCDate] [datetime] NOT NULL,
        [ID] [int] IDENTITY(1,1) NOT NULL,
     CONSTRAINT [PK_ShortInfoRunJobs] PRIMARY KEY CLUSTERED 
    (
        [ID] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    
    GO
    
    ALTER TABLE [srv].[ShortInfoRunJobs] ADD  CONSTRAINT [DF_ShortInfoRunJobs_InsertUTCDate]  DEFAULT (getutcdate()) FOR [InsertUTCDate]
    GO
  3. Tạo một tác vụ trong SQL Server Agent và nhận thông tin về những tác vụ đã được thực thi trong một thời gian dài (hơn 30 giây) hoặc không thể hoàn thành. Bạn cần thu thập thông tin này trong hai ngày qua:
    USE [DATABASE_NAME];
    GO
    
    truncate table [srv].[ShortInfoRunJobs];
    
    INSERT INTO [srv].[ShortInfoRunJobs]
               ([Job_GUID]
               ,[Job_Name]
               ,[LastFinishRunState]
               ,[LastDateTime]
               ,[LastRunDurationString]
               ,[LastRunDurationInt]
               ,[LastOutcomeMessage]
               ,[LastRunOutcome]
               ,[Server])
        SELECT [Job_GUID]
              ,[Job_Name]
              ,[LastFinishRunState]
              ,[LastDateTime]
              ,[LastRunDurationString]
              ,[LastRunDurationInt]
              ,[LastOutcomeMessage]
              ,LastRunOutcome
              ,@@SERVERNAME
          FROM [srv].[vJobRunShortInfo]
          where [Enabled]=1
          and ([LastRunOutcome]=0
          or [LastRunDurationInt]>=30)
          and LastDateTime>=DateAdd(day,-2,getdate());
    GO

    Tại đây bạn có thể đặt bộ lọc để loại bỏ tất cả các tác vụ không cần thiết. Ví dụ:những nhiệm vụ đề cập đến việc nhân rộng vì cần nhiều thời gian hơn để hoàn thành.

Tạo báo cáo HTML để gửi đến email của quản trị viên:

USE [DATABASE_NAME]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [srv].[GetHTMLTableShortInfoRunJobs]
    @body nvarchar(max) OUTPUT
AS
BEGIN
    /*
        generates an HTML-code for the tables of completed tasks
    */
    SET NOCOUNT ON;
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

    declare @tbl table (
                        Job_GUID                uniqueidentifier
                        ,Job_Name               nvarchar(255)
                        ,LastFinishRunState     nvarchar(255)
                        ,LastDateTime           datetime
                        ,LastRunDurationString  nvarchar(255)
                        ,LastOutcomeMessage     nvarchar(max)
                        ,[Server]               nvarchar(255)
                        ,ID                     int identity(1,1)
                       );

    declare
    @Job_GUID               uniqueidentifier
    ,@Job_Name              nvarchar(255)
    ,@LastFinishRunState    nvarchar(255)
    ,@LastDateTime          datetime
    ,@LastRunDurationString nvarchar(255)
    ,@LastOutcomeMessage    nvarchar(max)
    ,@Server                nvarchar(255)
    ,@ID                    int;

    insert into @tbl(
                        Job_GUID
                        ,Job_Name
                        ,LastFinishRunState
                        ,LastDateTime
                        ,LastRunDurationString
                        ,LastOutcomeMessage
                        ,[Server]
                    )
            select      Job_GUID
                        ,Job_Name
                        ,LastFinishRunState
                        ,LastDateTime
                        ,LastRunDurationString
                        ,LastOutcomeMessage
                        ,[Server]
            from    srv.ShortInfoRunJobs
            --order by LastRunDurationInt desc;

    if(exists(select top(1) 1 from @tbl))
    begin
        set @body='When analyzing these tasks execution, I have found out the tasks that either have failed with an error,
        or, it has taken more than 30 seconds for their execution :<br><br>'+'<TABLE BORDER=5>';

        set @[email protected]+'<TR>';

        set @[email protected]+'<TD>';
        set @[email protected]+'№ p/p';
        set @[email protected]+'</TD>';

        set @[email protected]+'<TD>';
        set @[email protected]+'GUID';
        set @[email protected]+'</TD>';

        set @[email protected]+'<TD>';
        set @[email protected]+'TASK';
        set @[email protected]+'</TD>';

        set @[email protected]+'<TD>';
        set @[email protected]+'STATUS';
        set @[email protected]+'</TD>';

        set @[email protected]+'<TD>';
        set @[email protected]+'DATE AND TIME';
        set @[email protected]+'</TD>';

        set @[email protected]+'<TD>';
        set @[email protected]+'DURATION';
        set @[email protected]+'</TD>';

        set @[email protected]+'<TD>';
        set @[email protected]+'MESSAGE';
        set @[email protected]+'</TD>';

        set @[email protected]+'<TD>';
        set @[email protected]+'SERVER';
        set @[email protected]+'</TD>';

        set @[email protected]+'</TR>';

        while((select top 1 1 from @tbl)>0)
        begin
            set @[email protected]+'<TR>';

            select top 1
            @ID                     =   [ID]
            ,@Job_GUID              =   Job_GUID
            ,@Job_Name              =   Job_Name                
            ,@LastFinishRunState    =   LastFinishRunState      
            ,@LastDateTime          =   LastDateTime            
            ,@LastRunDurationString =   LastRunDurationString   
            ,@LastOutcomeMessage    =   LastOutcomeMessage      
            ,@Server                =   [Server]                
            from @tbl
            order by LastRunDurationInt desc;

            set @[email protected]+'<TD>';
            set @[email protected]+cast(@ID as nvarchar(max));
            set @[email protected]+'</TD>';

            set @[email protected]+'<TD>';
            set @[email protected]+cast(@Job_GUID as nvarchar(255));
            set @[email protected]+'</TD>';

            set @[email protected]+'<TD>';
            set @[email protected]+coalesce(@Job_Name,'');
            set @[email protected]+'</TD>';

            set @[email protected]+'<TD>';
            set @[email protected]+coalesce(@LastFinishRunState,'');
            set @[email protected]+'</TD>';

            set @[email protected]+'<TD>';
            set @[email protected]+rep.GetDateFormat(@LastDateTime, default)+' '+rep.GetTimeFormat(@LastDateTime, default);--cast(@InsertDate as nvarchar(max));
            set @[email protected]+'</TD>';

            set @[email protected]+'<TD>';
            set @[email protected]+coalesce(@LastRunDurationString,'');
            set @[email protected]+'</TD>';

            set @[email protected]+'<TD>';
            set @[email protected]+coalesce(@LastOutcomeMessage, '');
            set @[email protected]+'</TD>';

            set @[email protected]+'<TD>';
            set @[email protected]+coalesce(@Server, '');
            set @[email protected]+'</TD>';

            delete from @tbl
            where [email protected];

            set @[email protected]+'</TR>';
        end

        set @[email protected]+'</TABLE>';
    end
    else
    begin
        set @body='The tasks, that have failed with an error or that have been executed for more than 30 seconds, have not been found';
    end

    set @[email protected]+'<br><br>For the detailed information, please refer to the table DATABASE_NAME.srv.ShortInfoRunJobs';
END

GO

Thủ tục được lưu trữ này tạo báo cáo HTML về các nhiệm vụ đã hoàn thành đã được thực thi trong 30 giây hoặc không hoàn thành được.

Kết quả

Trong bài viết này, tôi đã khám phá một ví dụ cụ thể về việc triển khai thu thập dữ liệu tự động hàng ngày về các tác vụ đã hoàn thành trong SQL Server Agent. Thông tin này giúp xác định các tác vụ đã được thực hiện trong một thời gian dài hoặc được hoàn thành với lỗi. Nó cho phép quản trị viên thực hiện các biện pháp để tránh những sai lầm như vậy trong tương lai. Ví dụ:có thể làm cho tác vụ chạy nhanh hơn hoặc đặt thời gian tối đa cho tác vụ được chỉ định.

Giải pháp này cũng giúp giám sát các vấn đề liên quan đến sao lưu. Tuy nhiên, chúng ta sẽ thảo luận về nó sau, vì thông báo về các nhiệm vụ quan trọng mỗi ngày một lần là không đủ. Cần phải gửi email về chúng ngay lập tức và thường xuyên cho đến khi lỗi được sửa.

Nếu bạn cần chọn dữ liệu từ nhiều máy chủ, thì có thể kết hợp các kết quả và gửi chúng `qua một email.

Tài liệu tham khảo:

»sysjobs
» sysjobservers

Đọc thêm:

Thu thập dữ liệu tự động của các thay đổi lược đồ cơ sở dữ liệu trong MS SQL Server

Thu thập dữ liệu tự động:Tệp cơ sở dữ liệu và ổ đĩa logic trong MS SQL Server

Định cấu hình thông báo thư cơ sở dữ liệu trong MS SQL Server


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Có thể chỉ định điều kiện trong Count () không?

  2. Tìm hiểu Luôn luôn BẬT Nhóm sẵn có giữa các Phiên bản Máy chủ SQL dựa trên Linux. Phần 1

  3. SMALLDATETIMEFROMPARTS () Ví dụ trong SQL Server (T-SQL)

  4. Làm thế nào để chọn tất cả các bản ghi từ một bảng mà không tồn tại trong một bảng khác?

  5. Sử dụng sp_help_jobschedule trong SQL Server