スキーマの変更がどのように発生したかを判断しますか?


21

昨日何か悪いことが起こりました。

少し前に作成されたビューは、最終的にレポートを破った誰かによって変更されました。残念ながら。誰かが(故意または無意識のうちに)PRODUCTIONデータベースでこの変更を行いました。

私の質問:この変更を誰(ユーザー名)が行ったかを知ることができる方法(スクリプト/ソフトウェア/フリーウェアなど)があり、そのユーザーの本番データベースへのアクセスを取り消すことができます。

私の質問が不明な場合は、コメントしてください。

回答:


36

これはデフォルトのトレースに記録されるため、「Schema Changes History」レポートに表示されるまで有効になっていて、ロールオーバーされていない限り、トレースされます。

Management Studioでこれにアクセスするには、データベースを右クリックして、コンテキストメニューから選択します。 Reports -> Standard Reports -> Schema Changes History

TSQLを介して同じ情報を取得するには、次を使用できます。

SELECT StartTime
       ,LoginName
       --,f.*
FROM   sys.traces t
       CROSS APPLY fn_trace_gettable(REVERSE(SUBSTRING(REVERSE(t.path),
                                                       CHARINDEX('\', REVERSE(t.path)), 
                                                       260)
                                             ) + N'log.trc', DEFAULT) f
WHERE  t.is_default = 1
       AND ObjectName = 'FOO'
       AND EventClass IN (46, /*Object:Created*/
                          47, /*Object:Dropped*/
                          164 /*Object:Altered*/ )

マーティンのおかげで、「FOO」を自分のビューに置き換えてクエリを実行しましたが、何も返されませんでした。なぜそれが起こるのか?ただし、サーバーでは実行しませんでした
-xorpower

1
@Xorpower- Object:Createdビューを変更せずにドロップして作成した場合に備えて、イベントを処理するように編集しました。サーバーで実行しないことの意味がわかりませんか?もちろん正しいインスタンスに接続する必要がありますが、アクセス許可があれば接続の場所は関係ありません。
マーティンスミス

おかげでマーティンが、結果はまだ同じまま
xorpower


3
@Xorpower-トレースがロールオーバーし、約11時間以上経過したものの詳細が失われたように見えます。デフォルトのトレースでは、5つのファイルのみが保持され、古いファイルは削除されます。これを確認するためだけに、サーバー上のファイルシステムでフォルダーを確認することをお勧めします。あなたはからフォルダのパスを取得することができますSELECT path FROM sys.traces where is_default=1
マーティン・スミス

19

マーティンは、(明示的に無効にされていない限り)通常はオンになっている管理監査トレースという最良の手段をすでに指摘しています。管理トレースで情報が見つからない場合(無効になっているか、リサイクルされていた)、ログバックアップから情報を取得できます。実稼働DBであるため、定期的なフルバックアップとログバックアップを伴う定期的なバックアップサイクルがあると想定しています。DDLが現在の復元されたログにあるように、インシデントの前後にデータベースを別のサーバーに復元する必要があります。次にfn_dblog()、ログを使用して検査するという簡単な問題です。

1つの方法は、トランザクション開始操作を行うことです。

select [Begin Time], [Transaction Name], [Transaction SID], * 
from fn_dblog(null, null)
where Operation = 'LOP_BEGIN_XACT';

ALTER VIEWがスタンドアロントランザクションで発行された場合(つまり、BEGIN TRANSACTION/で囲まれていない場合COMMIT)は、という名前のトランザクションを開始しCreatProc transactionます。それを探してください、そして、それ[Transaction SID]はあなたが望むログインSIDです。

別の可能性は、必要なビューでSCH_Mを取得したトランザクションを探すことです。

select [Lock Information], * 
from fn_dblog(null, null)
where [Lock Information] like '%' + cast(object_id('...') as varchar(10))+'%'
and [Lock Information] like '%LOCK_SCH_M%'
go

ビューがDROPに続いてCREATEによって変更された場合、オブジェクトIDが変更された可能性がありますが、少なくとも、最後にCREATEを実行したトランザクション(復元されたデータベース内のビューの現在のオブジェクトID)を取得することに注意してください トランザクションIDを使用して、戻ってトランザクション開始情報を取得します。

select [Begin Time], [Transaction Name], [Transaction SID], *
from fn_dblog(null, null)
where [Transaction ID] = '...'
and Operation = 'LOP_BEGIN_XACT';

[トランザクションSID]は、やはりあなたのものです。SUSER_SNAMEログインSIDからログイン名を取得するために使用します。SIDが0x01の場合、ログインがであったことを意味しますsa。これは、saパスワードを知っている個人がそれを実行できたことを意味します。


2
ログファイルの読み取りに関するヒント。これは、誰かがデフォルトのトレースを無効にした場合に便利です。
スタンレージョンズ

トランザクションSIDがnullの場合はどうなりますか?
evictednoise

@evictednoiseは、関連するログレコードを(別の質問で)投稿してください。複数の理由が考えられるため、ログレコードが実際の原因の特定に役立ちます。
レムスルサヌ

6

いいえ、DDLトリガーなどを介してログに記録した場合を除きます

そのデータベースのALTER権限、またはsysadmin / db_owner / ddl_adminロールのメンバーシップを確認する必要があります。これは、魔女狩りよりも一般的なレビューとしての方が良いでしょう。おそらく、承認されていない無許可の変更を行う権利を持つ他の人もいます


0

まだ行っていない場合は、SQL Server Management Studioで利用可能なスキーマ変更履歴レポートを確認してください。SQL Serverはデフォルトで変更をログに記録するように見えます(デフォルトのトレース)。このレポートを介してそのデータを表示できるはずです。残念なことに、これらのトレースファイルは時間が経過すると自動的に削除またはロールオーバーされるため、データはすでに失われている可能性があります。がんばろう!


おっと、気にしないで。マーティン・スミスは彼の答えですでにこのレポートを参照しているようです。リンクが役立つ場合に備えて、ここに残しておきます。
マークマジェ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.