데이터베이스의 변경 사항을 감지하는 방법 (DDL 및 DML)


13

클라이언트의 SQL 서버에 많은 데이터베이스가 있습니다. 이 데이터베이스는 개발 중이므로 개발자는 데이터를 디자인, 리팩토링 및 수정하는 등의 작업을 수행 할 수 있습니다. 거의 변경되지 않는 일부 데이터베이스가 있습니다. 내 고객은 모든 것을 안전하게 (백업) 유지하고 환경 관리에 시간을 투자해야합니다. (회사에는 DB 관리자 위치가 없습니다.) 긴 토론 후, 클라이언트는 복원 용이성으로 인해 매일 전체 백업 전략을 사용하기로 결정했습니다.

상황에 대한 요약은 다음과 같습니다.

  • 데이터베이스 수는 매일 달라질 수 있습니다.
  • 변경된 데이터베이스 (데이터 및 / 또는 구조가 변경됨)는 백업되어야합니다.
  • 변경되지 않은 데이터베이스는 백업하지 않아야합니다.
  • 솔루션은 데이터베이스 구조에 영향을 미치지 않습니다 (요구 사항이 제한되지 않음)
  • 이 "백업 엔진"은 자동으로 작동합니다.

주요 문제점 : 데이터베이스가 변경되었음을 감지하는 방법. 문제의 첫 번째 부분 (DDL 변경)은 DDL 트리거 를 사용하여 해결할 수 있습니다 . 그러나 데이터 변경 (DML 변경)은 문제입니다. DML 트리거를 모든 데이터베이스의 모든 테이블에 적용하여 변경 내용 (성능, 확장 개체 관리 등)을 추적 할 수는 없습니다. 백업 엔진은 각 데이터베이스를 백업 준비 상태로 표시하기 위해 모든 변경 사항을 추적해야합니다.

  • Change Data Capture 는 솔루션이지만 너무 무거워 보입니다 (SQL Server Enterprise Edition도 필요함).

  • 다른 방법은 데이터베이스 파일 변경 사항 (크기 또는 마지막 변경 시간)을 추적하는 것이지만 제대로 작동하지 않습니다. 데이터베이스가 예약 된 모든 여유 공간을 초과하고 sp_spaceused 가 해결책이 아닌 경우 크기를 변경할 수 있습니다 .

  • 추적은 솔루션이지만 성능 문제를 일으키고 추가 관리가 필요합니다.

통계와 같은 다른 데이터베이스 관리 개체에 영향을주지 않고 실제 데이터베이스 사용 크기를 계산할 수있는 솔루션이 있습니까? 테이블의 크기를 변경하지 않는 테이블 데이터의 변경이 트리거되지는 않지만 (아마 생각보다) 더 낫습니다. 실제로 SQL Server 2008에 대한 직접 또는 간접 솔루션을 찾고 있습니다.

의견, 해결책 및 생각에 감사드립니다.

추가 :

다음은 해결책입니다 ( Marian 덕분에 ).

Select
    NextLSN = MAX(fn.[Current LSN])
    ,Databasename = DB_NAME()
 from fn_dblog(NULL,    NULL) fn
     LEFT JOIN sys.allocation_units au
         ON fn.AllocUnitId = au.allocation_unit_id
     LEFT  JOIN sys.partitions p
         ON p.partition_id = au.container_id
     LEFT  JOIN sys.objects so
         ON so.object_id = p.object_id  
    WHERE 
    (
        (Operation IN 
       ('LOP_INSERT_ROWS','LOP_MODIFY_ROW',
            'LOP_DELETE_ROWS','LOP_BEGIN_XACT','LOP_COMMIT_XACT') 
            AND so.is_ms_shipped = 0)
        OR 
        ([Lock Information] like '%ACQUIRE_LOCK_SCH_M OBJECT%')
    )

그래서 이것을 작업의 일부로 구현 했습니까 ??? 나는 지난 24 시간 동안의 모든 변경 사항을 디렉토리로 매일 출력하는 방법 (예 : 오전 2시에)을 갖고 싶습니다. 그래서 나는 약간의 변경 로그를 가질 수 있습니다.
jcolebrand

@ jcolebrand 네, 했어요. 필자의 경우 데이터베이스 활동을 확인한 다음 백업을 수행해야합니다 (전체 또는 차등). fn_dblog 함수가 반환하는 LSN (로그 레코드의 기본 키)을 확인하고 있습니다. 그게 다야. 나는 그것이 당신의 경우에 효과가 있다고 생각하지 않습니다. fn_dblog가 반환 할 수있는 모든 데이터 기능을 조사하지는 않았지만 관련된 모든 정보를 반환하지는 않습니다. 보시다시피 많은 다른 시스템 테이블이 조인되었습니다. 쉬운 경우 우리는 많은 정상적이고 저렴한 도구를 가질 것입니다 :)
garik

답변:


7

한 가지 아이디어는 매일 스냅 샷을 작성하고 파일 모니터를 사용하여 디스크에서 스냅 샷 파일 크기를 모니터하는 것입니다. 스냅 샷은 데이터가 추가 될 때만 크기가 커지므로 실제 크기 (보고 된 크기)를 모니터링하는 도구를 찾는다면 올바른 아이디어가 될 것입니다.

지금 .. 나는 이것을 사용하지 않았으므로 기술적 인 통찰력을 줄 수는 없습니다 :-).

또 다른 아이디어는 로그에서 작업을 읽는 포럼 (db_fnlog .. 또는 무언가)에서 본 일부 기능을 사용하여 각 db의 트랜잭션 로그를 확인하는 것입니다 (물론 전체 복구 모드를 사용하는 경우). 삭제 / 삽입 / 업데이트가 있는지 확인하십시오.

그것들은 쉬운 일이 아닙니다. 그러나 나는 당신이 그것들이 유용하다는 것을 알기를 바랍니다.

추신 : 로그 읽기 기능이있는 기사를 찾았습니다 (fndblog, :-) : Jens K. Suessmeyer의 트랜잭션 로그를 읽으십시오 .


1
나는 db 파일 크기에 대해 이야기하지 않고 yyydb의 스냅 샷으로 create database xxxdb로 생성 된 스냅 샷 로컬 파일에 대해 이야기하지 않았습니다. 스냅 샷에 대한 자세한 내용은 msdn.microsoft.com/en-us/library/ms175158.aspx를 참조 하십시오 .
Marian

1
  • DDL 변경의 경우 기본 추적을 읽을 수 있습니다 .
  • CDC가 약간 무겁기 때문에 DML 수정의 경우 관련 이벤트 만 추적하는 자체 경량 서버 측 추적을 실행할 수 있습니다.

1

DDL 변경의 경우 DDL 트리거이지만 DML 변경에서는 3 가지 옵션을 사용해 볼 수 있습니다.

1) 변경 추적 2) CDC (데이터 변경 캡처) 3) 감사 기능

변경 내용 추적의 경우 다음 링크를 참조하십시오. http://www.mssqltips.com/sqlservertip/1819/using-change-tracking-in-sql-server-2008/

이 변경 내용 추적은 테이블이 변경되었거나 변경되지 않은 상태에서만 사용되지만 변경된 데이터를 찾는 것은 매우 어렵습니다. 변경된 데이터를 찾으려면 Chnage 데이터 캡처로 이동할 수 있습니다.

sqlserver ..의 Aduit의 경우 아래 링크를 확인할 수 있습니다 http://blogs.msdn.com/b/manisblog/archive/2008/07/21/sql-server-2008-auditing.aspx


1
+1이지만 CDC는 Enterprise Edition과 함께 제공
11

1

DML 변경의 경우 다음 기본 SQL Server 감사 기능을 활용할 수 있습니다.

  • SQL Server 변경 내용 추적
  • SQL Server 변경 데이터 캡처
  • SQL Server 감사

각각의 장점과 단점이 있지만 감사는 Microsoft에서 가장 최근에 도입 한 것이므로 현재 및 미래의 솔루션을 감싸는 것이 좋습니다.

감사 기능 만 사람 / 시간 / 방법에 대한 정보를 제공합니다.


0

추적 파일을 사용하여 ddl 변경 사항을 감지 할 수 있습니다. 아래는 변경 사항을 가져 오는 스크립트입니다.

SELECT 
    te.name AS eventtype
    ,t.loginname
    ,t.spid
    ,t.starttime
    ,t.objectname
    ,t.databasename
    ,t.hostname
    ,t.ntusername
    ,t.ntdomainname
    ,t.clientprocessid
    ,t.applicationname  
FROM sys.fn_trace_gettable
(
    CONVERT
    (VARCHAR(150)
    ,(
        SELECT TOP 1 
            value
        FROM sys.fn_trace_getinfo(NULL)  
        WHERE property = 2
    )),DEFAULT
) T 
INNER JOIN sys.trace_events as te 
    ON t.eventclass = te.trace_event_id 
WHERE eventclass=164

이 스크립트를 사용하여 테이블 및 스토어드 프로 시저에서 수정 사항을 발견 할 수 있습니다.

SELECT 
    SO.Name
    ,SS.name 
    ,SO.type_desc 
    ,SO.create_date
    ,SO.modify_date 
 FROM sys.objects AS SO
INNER JOIN sys.schemas AS SS 
    ON SS.schema_id = SO.schema_id 
WHERE DATEDIFF(D,modify_date, GETDATE()) < 50
AND TYPE IN ('P','U')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.