データベースの変更を検出する方法(DDLおよびDML)
-
16-10-2019 - |
質問
クライアントのSQLサーバーには多くのデータベースがあります。これらのデータベースは開発中であるため、開発者は設計、リファクタリング、データの変更などを行うことができます。めったに変更されないデータベースがいくつかあります。私のクライアントは、それらすべてを安全に保ち(バックアップ)、環境の管理に時間を費やす必要があります。 (会社にはDB管理者のポジションはありません。)長い議論の後、クライアントは復元が容易なため、毎日のフルバックアップ戦略を使用することを決定しました。
それで、ここに状況の要約があります:
- データベースの数は毎日異なる場合があります。
- 変更されたデータベース(データおよび/または構造が変更されたことを意味する)はバックアップされます。
- 変更されなかったデータベースはバックアップされてはなりません。
- 解決策はデータベース構造に影響を与えてはなりません(制限された要件ではありません)
- この「バックアップエンジン」は自動的に動作するものとします。
主な問題:データベースが変更されたことを検出する方法。 問題の最初の部分(DDLの変更)は、使用することで解決できます DDLトリガー. 。しかし、データの変更(DMLの変更)は問題です。すべてのデータベースのすべてのテーブルにDMLトリガーを適用して、変更を追跡することは不可能です(パフォーマンス、拡張オブジェクトの管理...)。バックアップエンジンは、すべての変更を追跡して、各データベースをバックアップの準備ができているとマークする必要があります。
データキャプチャを変更します ソリューションですが、重すぎるようです(SQL Server Enterprise Editionも必要です)。
別の方法は、データベースファイルの変更(サイズまたは最後の変更時間)を追跡することですが、正しく機能しません。データベースは、予約されたすべての空きスペースを超えてサイズを変更でき、 sp_spaceused 解決策ではありません。
トレースは解決策ですが、引き起こします パフォーマンスの問題 追加の管理が必要です。
他のデータベース管理オブジェクト(統計..など)に影響を与えることなく、実際のデータベース使用量を計算するソリューションはありますか?テーブルのサイズを変更しないテーブルのデータを変更してもトリガーはトリガーされないことを認めましたが、何もないよりはましです。本当にSQL Server 2008の直接的または間接的なソリューションを探しています。
コメント、解決策、考えをありがとう。
追加した:
これが解決策です(ありがとう マリアン):
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%')
)
解決
1つのアイデアは、毎日スナップショットを作成し、ファイルモニターを使用してディスクのスナップショットファイルサイズを監視することです。スナップショットは、そこにデータが追加された場合にのみサイズを拡大しているため、実際のサイズ(報告されたサイズ)を監視するツールを見つけるかどうかは有効なアイデアになります。
今..私はこれを使用していなかったので、技術的な洞察を与えることはできません:-)。
別のアイデアは、ログから操作を読み取るフォーラム(db_fnlog ..または何か)で見たいくつかの機能を使用して、各dbのトランザクションログ(もちろんフルリカバリモードを使用している場合)を確認することです。 、削除/挿入/更新があるかどうかを確認します。
それらは簡単なことではありません。しかし、私はあなたがそれらが便利だと思うことを願っています。
PS:ログ読み取り関数で記事を見つけました(ちなみにfndblogです:-): Jens K. Suessmeyerによるトランザクションログを読んでください.
他のヒント
- DDLの変更については、読むことができますデフォルトのトレース.
- DMLの変更については、CDCが少し重いことがわかるため、関連するイベントのみを追跡する独自の軽量サーバーサイドトレースを実行できます
DDLの変更の場合、DDLがトリガーしますが、DMLの変更3つの異なるオプションを使用してみることができます
1)追跡の変更2)CDC(データキャプチャの変更)3)監査機能
変更追跡について..以下のリンクを見ることができます http://www.mssqltips.com/sqlservertip/1819/using-change-tracking-in-scl-server-2008/
この変更追跡は、テーブルが変更されたかどうかにかかわらず使用されます...しかし、どのデータが変更されたかを見つけることは非常に困難です。
sqlserverでのアドーツについては、以下のリンクを確認できます http://blogs.msdn.com/b/manisblog/archive/2008/07/21/sql-server-2008-auditing.aspx
DMLの変更については、FollowinhネイティブSQL Server監査機能のいずれかを利用できます。
- SQLサーバーの変更追跡
- SQL Server Change Data Capture
- SQLサーバー監査
それぞれには利点と短所がありますが、監査はMicrosoftによって最新の導入されているため、現在および将来のソリューションを包み込んだことをお勧めします。
監査機能のみが、誰 /いつ /どのようにして情報を提供していることに注意してください
TRACEファイルを使用して、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')