データベース(DDLおよびDML)への変更を検出する方法


13

クライアントのSQLサーバーには多くのデータベースがあります。これらのデータベースは開発中であるため、開発者は設計、リファクタリング、データ変更などを行うことができます。ほとんど変更されないデータベースがいくつかあります。私のクライアントは、それらすべてを安全に(バックアップして)保持し、環境の管理に時間を費やさなければなりません。(会社にはDB管理者の立場はありません。)長い議論の末、クライアントは復元が容易なため、毎日の完全バックアップ戦略を使用することにしました。

状況の概要は次のとおりです。

  • データベースの数は毎日異なります。
  • 変更されたデータベース(データや構造が変更されたことを意味します)はバックアップされます。
  • 変更されていないデータベースはバックアップされません。
  • ソリューションはデータベース構造に影響を与えません(要件に制限はありません)
  • この「バックアップエンジン」は自動的に機能します。

主な問題:データベースが変更されたことを検出する方法。問題の最初の部分(DDLの変更)は、DDLトリガーを使用して解決できます。ただし、データの変更(DMLの変更)は問題です。DMLトリガーをすべてのデータベースのすべてのテーブルに適用して、変更(パフォーマンス、拡張オブジェクトの管理など)を追跡することはできません。バックアップエンジンは、すべての変更を追跡して、各データベースをバックアップ準備完了としてマークする必要があります。

  • 変更データキャプチャはソリューションですが、重すぎるようです(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

1つのアイデアは、毎日スナップショットを作成し、ファイルモニターを使用してディスク上のスナップショットファイルサイズを監視することです。スナップショットは、そこにデータが追加されたときにのみサイズが増加するため、実際のサイズ(報告されたサイズ)を監視するツールを見つけることができれば、それは有効なアイデアです。

今..私はこれを使用しなかったので、技術的な洞察をあなたに与えることはできません:-)。

別のアイデアは、ログから操作を読み取るフォーラム(db_fnlog ..など)で見た機能を使用して、各データベースのトランザクションログを検証することです(もちろん、完全復旧モードを使用している場合)。 、削除/挿入/更新があるかどうかを確認します。

これらは簡単なことではありませんが、役に立つと思います。

PS:ログ読み取り機能を持つ記事を見つけました(ちなみにfndblogです:-):Jens K. Suessmeyerがトランザクションログを読み取りました


1
私はdbファイルのサイズについてではなく、次のコマンドで作成されたスナップショットローカルファイルについて話しました。yyydbのスナップショットとしてデータベースxxxdbを作成します。スナップショットの詳細については、msdn.microsoft.com / en-us / library / ms175158.aspxを参照してください
マリアン

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/を参照してください。

この変更追跡は、テーブルが変更されたかどうかに関係なく使用されます...しかし、どのデータが変更されたかを見つけることは非常に困難です。

sqlserverのAduitについては、以下のリンクhttp://blogs.msdn.com/b/manisblog/archive/2008/07/21/sql-server-2008-auditing.aspxを確認できます。


1
1、しかし、CDCは、Enterprise Editionに同梱
garik

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.