MSSQL 모니터링 데이터/로그 파일 증가 실현 방법

며칠 전 모든 데이터베이스 서버 에 디스크 공간 을 감시 하 는 저장 과정 과 작업 을 배치 한 후(MS SQL 감시 디스크 공간 경고)오늘 갑자기 두 통 의 경고 메 일 을 받 았 습 니 다.좋 습 니 다.저장 계획 은 한편 이지 만 어떤 원인 으로 인해 디스크 공간 이 부족 한 지 분석 해 야 합 니까?갑 작 스 럽 게 급증 한 로그 파일 이나 시스템 업무 급증 으로 인 한 데이터 양 이 급증 한 것 일 까,아니면 역사 데이터 누적 원인 일 까......................................................매일(주파 수 를 조정 할 수 있 음)데이터 파일 의 정 보 를 수집 하고 한 표 에 넣 으 면 우리 가 데이터 파일 의 성장 변화 규칙 을 분석 하 는 데 편리 하고 심지어 데이터 파일 의 성장 폭 과 업무 변 화 를 관련 시 켜 분석 할 수 있다.그러면 다음은 나의 디자인 사고 와 실현 코드 이다.현 재 는 간단 한 실현 일 뿐 이 고 앞으로 계속 최적화 할 것 이다.약간의 기능 을 풍부하게 하 다.우선,데이터베이스 파일 의 역사적 성장 변화 정 보 를 저장 하기 위해 표 DiskCapacity History 를 만 듭 니 다.

USE  msdb;
GO

IF  EXISTS (SELECT 1 FROM dbo.sysobjects WHERE id = OBJECT_ID(N'') AND xtype='U')
    DROP TABLE DiskCapacityHistory;
GO

CREATE TABLE dbo.DiskCapacityHistory
(
    [Date_CD]            INT                     ,
    [DataBaseID]         INT                     ,
    [FileID]             INT                     ,
    [DataBaseName]       sysname                 ,
    [LogicalName]        VARCHAR(32)             ,
    [FileTypeDesc]       NVARCHAR(60)            ,
    [PhysicalName]       NVARCHAR(260)          ,
    [StateDesc]          NVARCHAR(60)           ,
    [MaxSize]            NVARCHAR(32)            ,
    [GrowthType]         NVARCHAR(8)             ,
    [IsReadOnly]         INT                     ,
    [IsPercentGrowth]    SMALLINT                ,
    [Size]               FLOAT                   ,
    [Growth_MOM_RAT]     FLOAT                   ,
    [Growth_YOY_RAT]     FLOAT                   ,
    CONSTRAINT PK_DiskCapacityHistory PRIMARY KEY(Date_CD, DataBaseID, FileID)    
);


EXEC sys.sp_addextendedproperty @name = N'MS_Description'
    , @value = ' '
    , @level0type = N'SCHEMA'
    , @level0name = N'dbo'
    , @level1type = N'TABLE'
    , @level1name = N'DiskCapacityHistory'
    , @level2type = N'COLUMN'
    , @level2name = N'Date_CD';

EXEC sys.sp_addextendedproperty @name = N'MS_Description'
    , @value = ' '
    , @level0type = N'SCHEMA'
    , @level0name = N'dbo'
    , @level1type = N'TABLE'
    , @level1name = N'DiskCapacityHistory'
    , @level2type = N'COLUMN'
    , @level2name = N'DataBaseID';

EXEC sys.sp_addextendedproperty @name = N'MS_Description'
    , @value = ' '
    , @level0type = N'SCHEMA'
    , @level0name = N'dbo'
    , @level1type = N'TABLE'
    , @level1name = N'DiskCapacityHistory'
    , @level2type = N'COLUMN'
    , @level2name = N'FileID';

EXEC sys.sp_addextendedproperty @name = N'MS_Description'
    , @value = ' '
    , @level0type = N'SCHEMA'
    , @level0name = N'dbo'
    , @level1type = N'TABLE'
    , @level1name = N'DiskCapacityHistory'
    , @level2type = N'COLUMN'
    , @level2name = N'DataBaseName';

 
 EXEC sys.sp_addextendedproperty @name = N'MS_Description'
    , @value = ' '
    , @level0type = N'SCHEMA'
    , @level0name = N'dbo'
    , @level1type = N'TABLE'
    , @level1name = N'DiskCapacityHistory'
    , @level2type = N'COLUMN'
    , @level2name = N'LogicalName';

 
EXEC sys.sp_addextendedproperty @name = N'MS_Description'
    , @value = ' '
    , @level0type = N'SCHEMA'
    , @level0name = N'dbo'
    , @level1type = N'TABLE'
    , @level1name = N'DiskCapacityHistory'
    , @level2type = N'COLUMN'
    , @level2name = N'FileTypeDesc';
   

   
EXEC sys.sp_addextendedproperty @name = N'MS_Description'
    , @value = ' '
    , @level0type = N'SCHEMA'
    , @level0name = N'dbo'
    , @level1type = N'TABLE'
    , @level1name = N'DiskCapacityHistory'
    , @level2type = N'COLUMN'
    , @level2name = N'PhysicalName';

EXEC sys.sp_addextendedproperty @name = N'MS_Description'
    , @value = ' '
    , @level0type = N'SCHEMA'
    , @level0name = N'dbo'
    , @level1type = N'TABLE'
    , @level1name = N'DiskCapacityHistory'
    , @level2type = N'COLUMN'
    , @level2name = N'MaxSize';

EXEC sys.sp_addextendedproperty @name = N'MS_Description'
    , @value = ' '
    , @level0type = N'SCHEMA'
    , @level0name = N'dbo'
    , @level1type = N'TABLE'
    , @level1name = N'DiskCapacityHistory'
    , @level2type = N'COLUMN'
    , @level2name = N'GrowthType';

EXEC sys.sp_addextendedproperty @name = N'MS_Description'
    , @value = ' '
    , @level0type = N'SCHEMA'
    , @level0name = N'dbo'
    , @level1type = N'TABLE'
    , @level1name = N'DiskCapacityHistory'
    , @level2type = N'COLUMN'
    , @level2name = N'IsReadOnly';

EXEC sys.sp_addextendedproperty @name = N'MS_Description'
    , @value = ' '
    , @level0type = N'SCHEMA'
    , @level0name = N'dbo'
    , @level1type = N'TABLE'
    , @level1name = N'DiskCapacityHistory'
    , @level2type = N'COLUMN'
    , @level2name = N'IsPercentGrowth';

EXEC sys.sp_addextendedproperty @name = N'MS_Description'
    , @value = ' (GB)'
    , @level0type = N'SCHEMA'
    , @level0name = N'dbo'
    , @level1type = N'TABLE'
    , @level1name = N'DiskCapacityHistory'
    , @level2type = N'COLUMN'
    , @level2name = N'Size';

EXEC sys.sp_addextendedproperty @name = N'MS_Description'
    , @value = ' (%)'
    , @level0type = N'SCHEMA'
    , @level0name = N'dbo'
    , @level1type = N'TABLE'
    , @level1name = N'DiskCapacityHistory'
    , @level2type = N'COLUMN'
    , @level2name = N'Growth_MOM_RAT';

EXEC sys.sp_addextendedproperty @name = N'MS_Description'
    , @value = ' (%)'
    , @level0type = N'SCHEMA'
    , @level0name = N'dbo'
    , @level1type = N'TABLE'
    , @level1name = N'DiskCapacityHistory'
    , @level2type = N'COLUMN'
    , @level2name = N'Growth_YOY_RAT';

GO

IF  OBJECT_ID(N'sp_diskcapacity_cal')  IS NOT NULL
    DROP PROCEDURE sp_diskcapacity_cal;
GO

그 다음 에 저 희 는 저장 과정 을 만 들 고 이 데이터 뱅 크 의 파일 에 관 한 정 보 를 수집 하고 통계 하 는 일 을 맡 습 니 다.환 비/동기 대비 정상 적 인 상황 은 일반적으로 환 비:  (지표 현재 값-지표 값(지난달 같은 날)/지표 값(지난달 같은 날).동기 대비:  (지표 현재 치-지표 치(작년 월 같은 날)/지표 치(작년 월 같은 날).사실은 매일 데이터 파일 의 변화 상황 을 주목 하면 이 코드 안의 환 비,동기 대비 의미 가 크 지 않다.사실은 우 리 는 환 비,동기 대비:환 비:(기준 현재 값-기준 치(어제)/기준 치(어제)를 이렇게 정의 할 수 있다.동기 대비:(지표 현재 치-지표 치(지난달))/지표 치(지난달)물론 이 네 가지 지 표를 모두 추가 할 수 있 습 니 다.비교 참고,중점 이 다 를 뿐 입 니 다.

IF  OBJECT_ID(N'sp_diskcapacity_cal')IS NOT NULL
    DROP PROCEDURE sp_diskcapacity_cal;
GO

CREATE PROCEDURE dbo.sp_diskcapacity_cal
AS
BEGIN

   INSERT INTO dbo.DiskCapacityHistory
   (
        [Date_CD]           ,
        [DataBaseID]        ,
        [FileID]            ,
        [DataBaseName]      ,
        [LogicalName]       ,
        [FileTypeDesc]      ,
        [PhysicalName]      ,
        [StateDesc]         ,
        [MaxSize]           ,
        [GrowthType]        ,
        [IsReadOnly]        ,
        [IsPercentGrowth]   ,
        [Size]               
   )
     SELECT CAST(REPLACE(CONVERT(varchar(10),GETDATE(),120),'-','') AS INT)
                                                                            AS DateCD        ,
            database_id                                                     AS DataBaseId    ,
            file_id                                                         AS FileID        ,
            DB_NAME(database_id)                                            AS DataBaseName  ,
            name                                                            AS LogicalName   ,
            type_desc                                                       AS FileTypeDesc  ,
            physical_name                                                   AS PhysicalName  ,
            state_desc                                                      AS StateDesc     ,
            CASE WHEN max_size = 0 THEN N' '
                 WHEN max_size = -1 THEN N' '
                 ELSE LTRIM(STR(max_size * 8.0 / 1024 / 1024, 14, 2)) + 'G'
            END                                                             AS MaxSize       ,
            CASE WHEN is_percent_growth = 1
                 THEN RTRIM(CAST(Growth AS CHAR(10))) + '%'
                 ELSE RTRIM(CAST(Growth AS CHAR(10))) + 'M'
            END                                                             AS Growth        ,
            Is_Read_Only AS IsReadOnly ,
            Is_Percent_Growth AS IsPercentGrowth ,
            CAST(size * 8.0 / 1024 / 1024 AS DECIMAL(8, 4))                 AS Size
     FROM   sys.master_files;

    
     MERGE INTO dbo.DiskCapacityHistory DM USING
     (
     SELECT M.Date_CD        ,
            M.DataBaseID     ,
            M.FileID         ,
            CASE WHEN N.SIZE IS NULL OR N.SIZE = 0 THEN 0 ELSE
                (M.SIZE - N.SIZE)/N.SIZE END AS Growth_MOM_RAT
     FROM dbo.DiskCapacityHistory M
      LEFT JOIN dbo.DiskCapacityHistory  N ON
              CAST(CAST(M.Date_CD AS CHAR(8)) AS DATE) = DATEADD(MONTH, 1, CAST(CAST(N.Date_CD AS CHAR(8)) AS DATE))
          AND M.DataBaseID = N.DataBaseID AND M.FileID = N.FileID
     WHERE M.Date_CD =  CAST(REPLACE(CONVERT(varchar(10),GETDATE(),120),'-','') AS INT)
     ) TMP
     ON
     (
            DM.Date_CD       = TMP.Date_CD     AND
            DM.DatabaseId    = TMP.DataBaseId  AND
            DM.FileId        = TMP.FileId
     )
     WHEN MATCHED THEN UPDATE SET
        DM.Growth_MOM_RAT = TMP.Growth_MOM_RAT;
END   
GO
참고 로 지난 2 년 동안 ORACLE 데이터 베 이 스 를 사 용 했 기 때문에 SQL SERVER 를 거의 접 하지 못 했 습 니 다.위의 기능 을 실현 할 때 저 는 ORACLE 과 SQL SERVER 의 큰 차 이 를 깊이 느 꼈 습 니 다.만약 에 PL/SQL 로 실현 하면 매우 편리 하고 빠 르 지만 T-SQL 로 저 에 게 상당히 고통스러운 부분 을 만 났 습 니 다.다음 에 기록 하고 비교 해 보 겠 습 니 다.
1.저 는 INT 를 사용 하여 날짜 데 이 터 를 저장 하기 때문에 DATE 형식 과 INT 형식 사이 에서 전환 해 야 합 니 다.두 가지 차 이 를 비교 해 보 겠 습 니 다. 1.1 DATE 유형 을 정형 으로 변환:T-SQL:SELECT CAST(REPLACE(CONVERT(varchar(10),GETDATE(),120),'-',')AS INT);PL/SQL:SELECT TO_CHAR(Date_CD, 'YYYYMMDD') FROM DUAL; 1.2 정형 을 DATE 형식 으로 변환(필드 DATECD)T-SQL:    SELECT CAST(CAST(DATE_CD AS CHAR(8)) AS DATE) FROM TEST;PL/SQL:    SELECT TO_DATE(DATE_CD, 'YYYY-MM-DD') FROM TEST;결론:순 전 히 개인 적 인 느낌 입 니 다.위의 스 크 립 트 의 단순 성,편리 성에 서 ORACLE 가 SQL SERVER 를 완 벽 히 이 긴 것 같 습 니 다. 2.계산 데이터 파일 의 증가 동기 대비,링 비례   1:SQL SERVER 2005 에는 MERGE 구문 기능 이 없습니다.위의 스 크 립 트 는 고 쳐 써 야 합 니 다.

UPDATEdbo.DiskCapacityHistory
 SET     GROWTH_MOM_RAT =( SELECTCASE WHEN N.SIZE IS NULL
                                            OR N.SIZE = 0 THEN 0
                                       ELSE ( dbo.DiskCapacityHistory.SIZE
                                              - N.SIZE ) / N.SIZE
                                  END AS Growth_MOM_RAT
                         FROM     dbo.DiskCapacityHistory N
                         WHERE    CAST(CAST(dbo.DiskCapacityHistory.Date_CD AS CHAR(8)) AS DATE) = DATEADD(MONTH,
                                                            1,
                                                            CAST(CAST(N.Date_CD AS CHAR(8)) AS DATE))
                                  AND dbo.DiskCapacityHistory.DataBaseID = N.DataBaseID
                                  AND dbo.DiskCapacityHistory.FileID = N.FileID
                       )
 WHEREdbo.DiskCapacityHistory.Date_CD = CAST(REPLACE(CONVERT(VARCHAR(10), GETDATE(), 120),
                                                     '-', '') AS INT)

UPDATEdbo.DiskCapacityHistory
 SET     GROWTH_YOY_RAT =( SELECTCASE WHEN N.SIZE IS NULL
                                            OR N.SIZE = 0 THEN 0
                                       ELSE ( dbo.DiskCapacityHistory.SIZE
                                              - N.SIZE ) / N.SIZE
                                  END AS Growth_YOY_RAT
                         FROM     dbo.DiskCapacityHistory N
                         WHERE    CAST(CAST(dbo.DiskCapacityHistory.Date_CD AS CHAR(8)) AS DATE) = DATEADD(MONTH,
                                                            12,
                                                            CAST(CAST(N.Date_CD AS CHAR(8)) AS DATE))
                                  AND dbo.DiskCapacityHistory.DataBaseID = N.DataBaseID
                                  AND dbo.DiskCapacityHistory.FileID = N.FileID
                       )
 WHEREdbo.DiskCapacityHistory.Date_CD = CAST(REPLACE(CONVERT(VARCHAR(10), GETDATE(), 120),
                                                     '-', '') AS INT)
혹시

CREATE TABLE #DiskCapacityHistory
    (
      DATE_CD INT ,
      DataBaseID INT ,
      FileID INT ,
      Growth_MOM_RAT FLOAT
    ) ;

  INSERTINTO #DiskCapacityHistory
        SELECT  M.DATE_CD ,
                M.DataBaseID ,
                M.FileID ,
                CASE WHEN N.SIZE IS NULL
                          OR N.SIZE = 0 THEN 0
                     ELSE ( M.SIZE - N.SIZE ) / N.SIZE
                END AS Growth_MOM_RAT
        FROM    dbo.DiskCapacityHistory M ,
                dbo.DiskCapacityHistory N
        WHERE   CAST(CAST(M.Date_CD AS CHAR(8)) AS DATE) = DATEADD(MONTH, 1,
                                                              CAST(CAST(N.Date_CD AS CHAR(8)) AS DATE))
                AND M.DataBaseID = N.DataBaseID
                AND M.FileID = N.FileID
                AND M.Date_CD = CAST(REPLACE(CONVERT(VARCHAR(10), GETDATE()
                                             - 1, 120), '-', '') AS INT)

  UPDATE dbo.DiskCapacityHistory
     SET Growth_MOM_RAT = M.Growth_MOM_RAT
    FROM #DiskCapacityHistory M
   WHERE dbo.DiskCapacityHistory.DATE_CD = M.DATE_CD
        AND dbo.DiskCapacityHistory.DataBaseID = M.DataBaseID
        AND dbo.DiskCapacityHistory.FileID = M.FileID ;
2:다행히 SQL 2008 은 ORACLE 의 MERGE 기능 을 모방 해 왔 습 니 다.그러나 T-SQL 은 ORACLE 데이터 뱅 크 의 강력 한 분석 함수 인 LAG 가 부족 합 니 다.이것 이 있 으 면 저 는 순환 비 를 계산 하 는 것 이 동기 대비 매우 편리 합 니 다.SQL 하나 로 해결 할 수 있 습 니 다.다음은 예 입 니 다.ORACLE 의 SQL 도 예 를 들 어 보 여 드 리 려 고 했 지만 표,숫자 를 만들어 야 하기 때문에 괴 롭 혔 습 니 다.
저자:소상 은자 출처:http://www.cnblogs.com/kerrycode/

좋은 웹페이지 즐겨찾기