그룹정책이 SQL 계정에 적용 되었을 때 계정의 상태를 확인 하는 쿼리입니다.

해당 쿼리는 SQL Server 2008 R2 이상에서 적용 하시기 바랍니다. (2005 버젼에서는 ExpirationDate 이 없습니다.)

 

SELECT name

,       LOGINPROPERTY ( name , 'IsExpired' ) AS [IsExpired]

,       LOGINPROPERTY ( name , 'IsLocked' ) AS [IsLocked]

,       LOGINPROPERTY ( name , 'PasswordLastSetTime' ) AS [PasswordLastSetTime]

,       DATEADD(DAY, CAST(LOGINPROPERTY(name, 'DaysUntilExpiration') AS int), GETDATE()) AS ExpirationDate

FROM sys.server_principals

WHERE type = 'S'




컬럼 설명

이름

만료 상태 확인 (0 : 정상)

잠김 상태 확인 (0 : 정상)

Password 마지막 변경일

Password 만료일

 

테스트 환경 그룹정책 내용


 

관련Site

https://msdn.microsoft.com/en-us/library/ms345412(v=sql.105).aspx


[문의사항]

서버 메모리 사용량 90% 임계치 초과

Svchost.exe (Eventlog, lmhosts) 메모리 사용량 증가

 

[환경]

Windows Server 2008 R2 SP1

SQL Server

 

[제안]


 

1. 모니터링 카운터

버퍼 캐시 메모리 부족을 확인하기 위해 SQLServer:Buffer Manager Buffer cache hit ratio, Page life expectancy 카운터를 모니터링 하시기 바랍니다.

아래 제시된 임계값은 일반적으로 알려진 허용 수치입니다. 절대값이 아니므로 임계값 이하라고해서 반드시 메모리가 부족한 상황은 아닙니다.

메모리 부족 판단이 어려울 경우 참고용으로 활용하실 수는 있습니다.

성능모니터(perfmon)으로 카운터를 추가해서 확인해도 관계 없습니다.

 

Buffer cache hit ratio – 캐시 적중률 (90% 이상)

SELECT (a.cntr_value * 1.0 / b.cntr_value) * 100.0 as BufferCacheHitRatio

FROM sys.dm_os_performance_counters  a

JOIN  (SELECT cntr_value,OBJECT_NAME

    FROM sys.dm_os_performance_counters 

    WHERE counter_name = 'Buffer cache hit ratio base'

        AND OBJECT_NAME = 'SQLServer:Buffer Manager') b ON  a.OBJECT_NAME = b.OBJECT_NAME

WHERE a.counter_name = 'Buffer cache hit ratio'

AND a.OBJECT_NAME = 'SQLServer:Buffer Manager'

 

Page life expectancy – 페이지 메모리 상주 시간 (300초 이상)

시간() 개념이기 때문에 무제한 증가하지도 값을 유지하지도 않습니다.

300 이상의 값까지 증가한 0으로 다시 초기화되는 상황은 정상이라고 판단해도 무방합니다.

SELECT object_name, counter_name, cntr_type

FROM sys.dm_os_performance_counters 

WHERE counter_name = 'Page life expectancy'

AND OBJECT_NAME = 'SQLServer:Buffer Manager'

 

 

2. Max Server Memory 현재 설정값 확인

sp_configure 'show advanced options', 1

go

reconfigure

go

 

sp_configure 'max server memory (mb)'

reconfigure

go

 

(아래 캡쳐에서는 2048MB(2GB) 설정됨)

 

3. Max Server Memory 설정

주의) 업무시간대에 진행하실 것을 권고 드립니다.

온라인 중에 적용 가능하지만, Plan Cache 초기화되어 적용 얼마간 CPU 사용량이 급증하고 성능이 저하될 수 있습니다.

-- ) 10GB(10240MB)로설정

sp_configure 'max server memory (mb)', 10240

reconfigure

go

 


'Microsoft > SQL' 카테고리의 다른 글

SQL Account expired date 확인 방법  (0) 2018.09.07
트랜젝션 로그 불리는 방법  (0) 2018.08.03
Disk I/O Query  (0) 2018.08.03
DBCC SHRINKFILE & Internal  (0) 2018.08.03

 

 

/*


데이터가 있는 테이블을 자가 복제 하여 트랜젝션 로그를 늘릴 수 있습니다.

해당 테스트에서 사용 하는 테이블 [AdventureWorks2012].[Person].[Person]  [AdventureWorks2012] DB 에서 용량이 가장 테이블 입니다.

sp_helpdb [DatabaseName] 로 중간 중간 파일의 용량을 확인 합니다.

 

truncate table [dbo].[Person]

*/

 

--1 단계 테이블을 생성 합니다.

SET ANSI_NULLS ON

GO

 

SET QUOTED_IDENTIFIER ON

GO

 

CREATE TABLE [dbo].[Person](

        [BusinessEntityID] [int] NULL,

        [PersonType] [nchar](2) NULL,

        [NameStyle] [bit] NULL CONSTRAINT [DF_Person_NameStyle]  DEFAULT ((0)),

        [Title] [nvarchar](8) NULL,

        [FirstName] [nvarchar](50) NULL,

        [MiddleName] [nvarchar](50) NULL,

        [LastName] [nvarchar](50) NULL,

        [Suffix] [nvarchar](10) NULL,

        [EmailPromotion] [int] NULL CONSTRAINT [DF_Person_EmailPromotion]  DEFAULT ((0)),

        [AdditionalContactInfo] [xml] NULL,

        [Demographics] [xml] NULL,

        [rowguid] [uniqueidentifier] NULL,

        [ModifiedDate] [datetime] NULL

) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

 

GO

--2단계 원본 테이블에서 데이터를 가져 옵니다.

 

 

INSERT [dbo].[Person] (BusinessEntityID, PersonType, NameStyle, Title, FirstName, MiddleName, LastName, Suffix, EmailPromotion, AdditionalContactInfo, Demographics, rowguid, ModifiedDate)

SELECT BusinessEntityID, PersonType, NameStyle, Title, FirstName, MiddleName, LastName, Suffix, EmailPromotion, AdditionalContactInfo, Demographics, rowguid, ModifiedDate FROM [AdventureWorks2012].[Person].[Person]

 

--데이터 백업용 테이블을 생성 합니다.

SELECT * INTO Person2 FROM [dbo].[Person]

 

--3단계 자가 복제를 시작 합니다. 순서는 (테이블 1에 데이터 입력 -> 테이블 2 데이터 입력 -> 테이블 1 Delete ) 입니다.

 

DECLARE @int int

SET @int = 0

WHILE (@int < 5)

BEGIN

 

INSERT [dbo].[Person] (BusinessEntityID, PersonType, NameStyle, Title, FirstName, MiddleName, LastName, Suffix, EmailPromotion, AdditionalContactInfo, Demographics, rowguid, ModifiedDate)

SELECT BusinessEntityID, PersonType, NameStyle, Title, FirstName, MiddleName, LastName, Suffix, EmailPromotion, AdditionalContactInfo, Demographics, rowguid, ModifiedDate FROM [dbo].[Person2]

 

INSERT [dbo].[Person2] (BusinessEntityID, PersonType, NameStyle, Title, FirstName, MiddleName, LastName, Suffix, EmailPromotion, AdditionalContactInfo, Demographics, rowguid, ModifiedDate)

SELECT BusinessEntityID, PersonType, NameStyle, Title, FirstName, MiddleName, LastName, Suffix, EmailPromotion, AdditionalContactInfo, Demographics, rowguid, ModifiedDate FROM [dbo].[Person]

 

DELETE [dbo].[Person]

 

SET @int = @INT +1

 

END

 

/*

 

 

(19972 행이 영향을 받음)

 

(39944 행이 영향을 받음)

 

(39944 행이 영향을 받음)

 

(59916 행이 영향을 받음)

 

(59916 행이 영향을 받음)

 

(59916 행이 영향을 받음)

 

(119832 행이 영향을 받음)

 

(119832 행이 영향을 받음)

 

(119832 행이 영향을 받음)

 

(239664 행이 영향을 받음)

 

(239664 행이 영향을 받음)

 

(239664 행이 영향을 받음)

 

(479328 행이 영향을 받음)

 

(479328 행이 영향을 받음)

 

(479328 행이 영향을 받음)

 

 

sp_helpdb [SUNY]

SUNY    1       C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\SUNY.mdf        PRIMARY 1583104 KB     Unlimited      1024 KB data only

SUNY_log       2       C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\SUNY_log.ldf   NULL    4632576 KB     2147483648 KB  10%        log only

 

*/

 

 

*/


[오류 사항]

  • 오류 : 오류 메시지는 SQL Server I/O 대한 병목 현상을 나타냅니다.
  • sql server has encountered 1 occurrence(s) of i/o requests taking longer than 15 seconds to complete
  • autogrow of file 'templog' in database 'tempdb' was cancelled by user or timed out after 117437ms
  • 담당자: 김석수 책임
  • 시간: 2시간

 

 

[추후 동일 증상 발생 확인 사항]

  1. 현재 대기 보류 중인 I/O 확인 합니다.

SELECT SUM(pending_disk_io_count) AS [Number of pending I/Os] FROM sys.dm_os_schedulers

 

  1. 1 쿼리에서 보고 I/O 카운터에 대하여 세부 사항을 확인 합니다.
  • IO_Pending 값이 0 이면 SQL Server 아직 I/O 처리 하지 않은 입니다.
  • IO_Pending 값이 1 이면 Windows 에서 아직 I/O 처리 하지 않은 입니다.

SELECT *  FROM sys.dm_io_pending_io_requests

 

  1. 보류 중인 I/O 통해서 디스크 병목 현상을 확인 합니다.

SELECT DB_NAME(mf.database_id) AS [Database] , mf.physical_name ,r.io_pending , r.io_pending_ms_ticks , r.io_type , fs.num_of_reads , fs.num_of_writes

     FROM sys.dm_io_pending_io_requests AS r INNER JOIN sys.dm_io_virtual_file_stats(NULL, NULL)

                                                                 AS fs ON r.io_handle = fs.file_handle INNER JOIN sys.master_files

                                           AS mf ON fs.database_id = mf.database_id

     AND fs.file_id = mf.file_id ORDER BY r.io_pending , r.io_pending_ms_ticks DESC ;

 

  1. I/O 유발 쿼리를 찾습니다.

select top 5 (total_logical_reads/execution_count) as avg_logical_reads,

                   (total_logical_writes/execution_count) as avg_logical_writes,

           (total_physical_reads/execution_count) as avg_physical_reads,

           Execution_count, statement_start_offset, p.query_plan, q.text

from sys.dm_exec_query_stats

      cross apply sys.dm_exec_query_plan(plan_handle) p

      cross apply sys.dm_exec_sql_text(plan_handle) as q

order by (total_logical_reads + total_logical_writes)/execution_count Desc

 

  1. 테이블 당 인덱스 사용 통계 / 테이블 가장 많은 I/O 작업을 유발하는 테이블을 확인 합니다.

SELECT d.name as [Database],  OBJECT_NAME(S.[OBJECT_ID]) AS [OBJECT NAME],         

I.[NAME] AS [INDEX NAME],         

USER_SEEKS,         

USER_SCANS,         

USER_LOOKUPS,         

USER_UPDATES

FROM     SYS.DM_DB_INDEX_USAGE_STATS AS S         

INNER JOIN SYS.INDEXES AS I ON I.[OBJECT_ID] = S.[OBJECT_ID]              

AND I.INDEX_ID = S.INDEX_ID

Join sys.Databases d on s.database_id = d.database_id

WHERE    OBJECTPROPERTY(S.[OBJECT_ID],'IsUserTable') = 1

Order by USER_SEEKS + USER_SCANS + USER_LOOKUPS + USER_UPDATES desc

 

 

SELECT d.name, t.name, OBJECT_NAME(A.[OBJECT_ID]) AS [OBJECT NAME],      

 I.[NAME] AS [INDEX NAME],      

  A.LEAF_INSERT_COUNT,       

  A.LEAF_UPDATE_COUNT,       

  A.LEAF_DELETE_COUNT

 

FROM   SYS.DM_DB_INDEX_OPERATIONAL_STATS (NULL,NULL,NULL,NULL ) A       

INNER JOIN SYS.INDEXES AS I          ON I.[OBJECT_ID] = A.[OBJECT_ID]  

join sys.tables t on i.object_id = t.object_id     

join sys.databases d on a.database_id = d.database_id

AND I.INDEX_ID = A.INDEX_ID WHERE  OBJECTPROPERTY(A.[OBJECT_ID],'IsUserTable') = 1

order by A.LEAF_INSERT_COUNT + A.LEAF_UPDATE_COUNT + A.LEAF_DELETE_COUNT desc

 

  • Tempdb 증가 원인 추적

USE TEMPDB;

 

-- TEMPDB allocated by session:

select *, (allocated_mb - deallocated_mb)reserved_mb from

(

select session_id

   ,(((sum(internal_objects_alloc_page_count + user_objects_alloc_page_count)*8024)/1024)/1024) as allocated_mb

   ,(((sum(internal_objects_dealloc_page_count + user_objects_dealloc_page_count)*8024)/1024)/1024) as deallocated_mb

from sys.dm_db_task_space_usage

group by session_id

) x where allocated_mb > 0;

 

-- TEMPDB allocated by object:

select o.type_desc

, substring(o.name,1,charindex('__',o.name)+1)+right(o.name,12) table_shortname

, si.name index_name

, case si.index_id when 0 then 'HEAP' when 1 then 'CLUSTERED' else 'NONCLUSTERED' end index_type

, row_count

, ((reserved_page_count * 8024) / 1024 / 1024)reserved_mb

, create_date

from sys.dm_db_partition_stats ps

left join sys.objects o on ps.object_id = o.object_id

left join sys.indexes si on si.object_id = o.object_id and si.index_id = ps.index_id

where is_ms_shipped = 0

order by reserved_page_count desc;

 

-- TEMPDB Data/Log File Auto Growth events:

DECLARE @filename VARCHAR(500)

SELECT @filename = SUBSTRING(path, 0,LEN(path) - CHARINDEX('\',REVERSE(path)) + 1)+ '\Log.trc'

   FROM sys.traces

      WHERE is_default = 1 ;

SELECT TOP 100

  te.Name AS EventName

  ,StartTime

  ,NTDomainName

  ,NTUserName

  ,LoginName

  ,ApplicationName

  ,HostName

  ,DatabaseName

  ,Filename

  ,IntegerData/128 [Size MB]

  ,CAST(Duration/1000000. AS DECIMAL(20,2)) AS [Duration sec]

  ,EndTime

  ,SPID

  ,SessionLoginName

  ,Error

  ,Success

  ,IsSystem

FROM fn_trace_gettable(@fileName, DEFAULT) gt

  INNER JOIN sys.trace_events te ON EventClass = te.trace_event_id

WHERE EventClass IN(92, 93) -- Data/Log File Auto Grow

AND DatabaseName = 'tempdb'

ORDER BY StartTime DESC;

 

  • Tempdb 대한 추적 플래그 T1118 을 설정 합니다.
  • DBCC traceon(1118, -1)

 


  • 사용 Script
    1. DBCC SHRINKFILE Automation Script
    • 대상 장비 변경 시 아래 변수만 수정하시면 됩니다.
    • @TargetSizeMB : SHRINKFILE 작업 데이터 파일 크기
    • @ShrinkUnitSize
    • SHRINKFILE 수행 단위(MB), 값이 경우 서비스에 영향을 줄 수 있으며, 일반적으로 1GB 혹은 사용량이 적을 경우 5GB까지 변경 사용
    • 사용량이 많은 시스템일 경우 100MB/512MB 조절 사용 필요, ShrinkfileSize를 줄일 경우 시스템 영향도를 줄일 수 있습니다.
    • @DatabaseName : SHRINKFILE 대상 데이터베이스 이름, 가급적 해당 데이터베이스 이동 사용(use 데이터베이명 혹은 SSMS SHRINKFILE 대상 DB 이동)

    SET NOCOUNT ON

    use 'SHRINKFILE데이터베이스명

    GO 

    DECLARE            

           @shrinkUnitSize            INT                        -- Unit of Shrinkfile Size

    ,      @TotalSizeMB        INT                        -- Current DataFile Size

    ,      @TargetSizeMB       INT                        -- Size Of Target

    ,      @filename                  VARCHAR(50)         -- Shrinkfile File Name

    ,      @start_time                DATETIME            -- Start Time

    ,      @databaseName       SYSNAME                    -- Target Database Name

    ,      @loopCnt                   INT                        -- loop Variables

     

    SET @TargetSizeMB = 300000  -- 현재 데이터파일 크기

    SET @shrinkUnitSize = 500 -- SHRINKFILE Size 단위(MB) - 초기 500MB

    SET @DatabaseName = 'SHRINKFILE데이터베이스명'

    SET @loopCnt = 1

     

    --SET Current Database Size, Change FileId or Set the FileName, 데이터베이스 Logical Finename

    SELECT @TotalSizeMB = size/128, @filename = name

      FROM sys.sysaltfiles where dbid=db_id(@DatabaseName) and fileid = 1

     

    --SHRINKFILE 결과

    SELECT @TotalSizeMB AS CurrentSizeMB, GETDATE() AS StartTime

     

    WHILE (@TotalSizeMB > @TargetSizeMB) -- for Loop Shrinkfile to @TargetSize

    BEGIN

             SET @start_time = GETDATE()

             SET @TotalSizeMB = @TotalSizeMB - @shrinkUnitSize       

     

             DBCC SHRINKFILE (@filename, @TotalSizeMB) WITH NO_INFOMSGS

     

             PRINT 'idx = ' + CAST(@loopCnt AS varchar(10)) +

                  ', totalSizeMB = ' + CAST(@TotalSizeMB AS varchar(10))

                  + ', duration = ' + CAST(DATEDIFF(s, @start_time, getdate()) AS varchar(10))

     

             SET @loopCnt = @loopCnt + 1

    END

     

    --SHRINKFILE 결과

    SELECT @TotalSizeMB AS ShrinkSizeMB, GETDATE() AS EndTime

    GO

     

     

    1. DBCC SHRINKFILE internal
    • DBCC SHRINKFILE DbccSpaceReclaim->DbccFilesCompact->DbccLOBCompact 입니다.
    • DbccSpaceReclaim : DML구문으로 인해 발생 미사용 Extents 대한 Clean-up 데이터 이동에 사용 Extents 대한 제거 작업
    • DbccFilesCompact : Truncate 대상 이전에 있는 페이지를 이동하고 Truncation 수행
    • DBCC SHRINKFILE 파일의 지점부터 수행 순차적으로 수행 됩니다. 지정에 위치한 Extents들을 데이터 파일 비어 있는 공간으로 이동을 하게 되고,

       이 단계에서 인덱스 Page들에 대한 Linked List Chain 느슨하게 풀리게 되면서 인덱스 조각도가 심화되는 상황이 발생 됩니다.

    • DbccLOBCompact : LOB(Large Object) 대한 Compact 작업 수행

    è 데이터 파일에 대한 DBCC SHRINKFILE 성능 저하 발생 구간

    Step

    Command

    Description

    1

    DbccSpaceReclaim

    Clean up deferred allocations and purge empty extents preparing for data moves.  

    2

    DbccFilesCompact

    Moves pages beyond the target to before the target and truncate file as required.

    3

    DbccLOBCompact

    Compacting the LOB data.

     




    è 1GB짜리 데이터 파일에 대한 SHRINKFILE 진행


    1. 미사용 Extents 대한 Clean-up 데이터 이동에 사용 Extents 대한 제거 작업이 진행 되고, 1GB 데이터파일의 부분의 여유 공간을 확인합니다. -> DbccSpaceReclaim
    2. 750MB 이내에 할당되지 않은 Page 대한 정보를 수집합니다.
    3. 750MB->1GB 사이에 위치한 GAM(Global Allocation Map) Marking되어 있는 모든 페이지를 검색 , Truncation 수행되어야 하는 위치(750MB->1GB=250MB)에 할당되어 있는 Page(데이터 혹은 인덱스)들을 에서 조회한

    할당되지 않은 Page 이동합니다. -> DbccFilesCompact

    1. DBCC SHRINKFILE 구문에 TRUNCATEONLY 구문이 명시되어 있지 않은 경우, LOB(Large Object) 대한 Compact작업이 수행되게 됩니다. -> DbccLOBCompact
    2. DBCC SHRINKFILE 옵션
    • TRUNCATEONLY : 파일 끝의 모든 여유 공간을 운영 체제로 해제하지만 파일 내에서 페이지 이동을 수행하지 않습니다. 데이터 파일은 마지막으로 할당된 익스텐트까지만 축소됩니다
    • NOTRUNCATEONLY : target_percent 지정하거나 지정하지 않고 데이터 파일의 끝에 있는 할당된 페이지를 파일 앞의 할당되지 않은 페이지로 이동합니다파일 끝의 여유 공간이 운영 체제에 반환되지 않고, 파일의 물리적 크기가 변경되지 않습니다. 그러므로 NOTRUNCATE 지정하면 파일이 축소되지 않는 것처럼 보입니다.

    + Recent posts