web-dev-qa-db-ja.com

テーブルへの更新を追跡するための拡張イベントの使用

更新され続けるテーブルがあり、どこから更新が行われるのか誰にもわかりません。私はそれらがEntity Frameworkから来ているのではないかと思いますが、この理論を証明するために、拡張イベントを介してUPDATEと関連情報をキャプチャしたいと考えています。

私はSQL 2014 Enterpriseを使用しており、exec_prepared_sqlおよびsql_statement_startingイベントを使用してその情報を取得しようとしています。ここに私がこれまでに持っているものがあります:

CREATE EVENT SESSION [Query Trace] ON SERVER 
ADD EVENT sqlserver.exec_prepared_sql(
    ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_id,sqlserver.database_name,sqlserver.plan_handle,sqlserver.session_id,sqlserver.sql_text,sqlserver.username)
    WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%UPDATE %') AND [sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%TableA%') AND [sqlserver].[database_id]=(123))),
ADD EVENT sqlserver.sql_statement_starting(
    ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_id,sqlserver.database_name,sqlserver.plan_handle,sqlserver.session_id,sqlserver.sql_text,sqlserver.username)
    WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%UPDATE %') AND [sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%TableA%') AND [sqlserver].[database_id]=(123)))
ADD TARGET package0.event_file(SET filename=N'E:\ExtendedEvent\Query-Trace.xel')
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)
GO

これはうまく機能しているようです。私はそれをテストし、通常のUPDATEステートメントとsp_executesqlで呼び出されたステートメントの両方をキャプチャすることができました。しかし、私はまだ何かが足りません。テーブル内のデータはまだ変更されており、この拡張イベントはそれを行うUPDATEをキャプチャしていません。

だから、私の質問は:

1)Entity Frameworkからのアップデートをキャプチャするために、拡張イベントで他に監視する必要があるものはありますか?

2)これには、拡張イベントの代わりに使用する必要があるものはありますか?

ありがとう!

7
Eric Cobb

SQL Server Enterprise Editionを使用している場合(または2016 SP1より新しいエディションを実行している場合)、SQLAudit機能を使用することをお勧めします。これにより、テーブルに誰が触れているか、および実行されているコマンドに関する詳細な情報が得られます。

このような場合、 データベース監査仕様サーバー監査 (監査の書き込み先を定義するために使用)を併用し、スコープを指定します。監視するテーブル。次に、変更をパブリックロールにスコープすることで、発生するすべての変更をキャプチャします。

このスクリプトによって、そこに到達するはずです(開発環境でテストし、監視するテーブルに関連する部分を置き換えます)。

USE [master]

GO

CREATE SERVER AUDIT [Audit-TblChanges]
TO FILE 
(   FILEPATH = N'C:\SQLAudit'
    ,MAXSIZE = 0 MB
    ,MAX_ROLLOVER_FILES = 2147483647
    ,RESERVE_DISK_SPACE = OFF
)
WITH
(   QUEUE_DELAY = 1000
    ,ON_FAILURE = CONTINUE
)

GO

USE [YourDatabase]
GO

CREATE DATABASE AUDIT SPECIFICATION [DatabaseAuditSpecification-MyTable]
FOR SERVER AUDIT [Audit-TblChanges]
ADD (UPDATE ON OBJECT::[YourTable] BY [public]),
ADD (INSERT ON OBJECT::[YourTable] BY [public])

GO


USE [master]
GO
ALTER SERVER AUDIT [Audit-TblChanges] WITH (STATE = ON);

USE [YourDatabase]
GO
ALTER DATABASE AUDIT SPECIFICATION [DatabaseAuditSpecification-MyTable] WITH (STATE = ON);
GO

GUIを使用してデータをすばやく読み取るか、または sys.fn_get_audit_file を使用してSQL Serverから直接データをクエリできます。

9
Nic