web-dev-qa-db-ja.com

削除または更新レコードの検索

ここ数か月間に3つのインシデントがあり、テーブル内のレコードが削除されたか、テーブル全体で値がゼロに更新されました。私たちは、権限を持ち、データベースを更新する責任を持つ4人のチームで構成されています。残念なことに、誰も変更の実施を認めていません。

今後、これらの取引の記録を残していきたいと思います。他の人がこれらの変更を追跡するために何を使用しているのだろうと思っていましたか?変更を追跡するソフトウェアを使用していますか、それともストアドプロシージャやトレースファイルを作成していますか?誰かが自分の施設でこれを設定している場合、私は彼らが何を使用しているのか知りたいのですが。トレースファイルには、ログイン名のマシン番号やsqlステートメントなどの情報が含まれているため、事前に設定しておけば、情報が得られます。

これらの変更が行われたときに、データベースとトランザクションログのコピーがあります。これらの古いファイルを使用して、原因を突き止めるために何かできることはありますか?返信してくださった方には、事前に感謝します。 SQL Server 2005を使用しています。

7
kdis

fn_dblogは、他のコメンテーターが言ったように、後方を見る方法です。

ユーザーがストアドプロシージャを介してデータを変更することのみを許可することは、これを最初に防ぐための優れた方法です。ロジックを追加して、ユーザーが不要なレコードを大量に変更したり、正しい値を提供したりする必要がないようにすることができます。アップデート用。つまり、ユーザーが現在データにアクセスしている方法に応じて、アプリケーションを変更する必要があります。それは可能かもしれないし、できないかもしれない。

それができない場合は、SQL 2005ですばやく簡単な方法として、トリガーを使用してテーブルレベルでDML監査を実行します。 (SQL Server 2008以降には、監査ツールが組み込まれています)。

問題の簡単な解決策は次のとおりです。


drop table audit_test
go
create table audit
(
uname varchar(50),
[date] datetime,
what nvarchar(4000),
Host varchar(50),
)
go 

create trigger ddlcheck on tbl_example 
for update, delete
as
declare @tbltmp table(eventtype nvarchar(30),para smallint, strsql nvarchar(4000))
insert into @tbltmp exec ('dbcc inputbuffer('+@@spid+')')
insert into audit_test select SUSER_NAME(), GETDATE(),  strsql ,  Host_NAME() from @tbltmp

これは、クエリがテーブルを更新するか、テーブルから削除しようとするたびに発生します。それは使用しています DBCC inputbufferhttp://msdn.Microsoft.com/en-us/library/ms187730(v = sql.90).aspx )発行されたコマンドを取得します。これにより、特定のテーブルに対して発行されたすべての更新ステートメントと削除ステートメントが入力されたテーブルが得られます。さらに、誰がいつどこでいつ声明を出したかを記録します。

これはビジーなテーブルで大量のログデータになる可能性があるため、トリガーを次のように変更することで、「悪い」クエリ(たとえば、1000行以上を更新/削除するクエリ)のみをキャッチするように制限できます。


create trigger ddlcheck on tbl_example 
for update, delete
as
declare @cnt integer
select @cnt=count(1) from deleted
if @cnt>1000
begin
  declare @tbltmp table(eventtype nvarchar(30),para smallint, strsql nvarchar(4000))
  insert into @tbltmp exec ('dbcc inputbuffer('+@@spid+')')
  insert into audit_test select SUSER_NAME(), GETDATE(),  strsql ,  Host_NAME() from @tbltmp
end

これにより記録されるデータは少なくなりますが、トリガーは引き続きすべての操作に対して「評価」する必要があるため、パフォーマンスに影響があり、測定およびテストが必要になる場合があります。これはまた、ユーザーが個々のステートメントをたくさん送信した場合のアクションを見逃します。

キャッチしません:


delete from tbl_example where id=1
delete from tbl_example where id=2
.....
delete from tbl_exampe where id=1000

キャッチします


delete from tbl_example where id>0 and id<1001

これが将来に役立つことを願っています。

5
Stuart Moore

本番データベースの監査には ApexSQL Log を使用します。誰がいつレコードを削除または更新したかを表示できます。また、データオブジェクトの挿入とCreate/alter/dropステートメントも追跡します。

ApexSQLログはトランザクションログからこれらのトランザクションを読み取ることができるため、これらの変更が行われたときにデータベースとトランザクションログのコピーを用意しておくことは良いことです。将来的に変更を追跡するためにそれを使用することを計画している場合、オンライントランザクションログまたはトランザクションログバックアップに、読み取りたいすべてのトランザクションが含まれていることを確認できる場合にのみ、データベースを完全復旧モデルにする必要があります。スペースを節約するためにトランザクションログのバックアップを圧縮します

過去24時間のトランザクションログバックアップを読み取り、トランザクションをHTMLファイルにエクスポートするようにスケジュールされた夜間ジョブがあります。情報が必要な場合は、ファイルを確認し、トランザクションログのバックアップが削除されても心配しません(30日後に削除します)

1