web-dev-qa-db-ja.com

データベースまたはデータベースファイルの自動拡張の原因となったプロセスを見つける方法

Tempdbに飢えているプロセスがありますが、このプロセスを特定するのに苦労しています。

これを達成する方法はありますか?

TempdbがT:\ドライブで以前に再利用したスペースに成長したため、警告を受けました。この場合も、ディスクには10MBが残っています。今朝の午前10時18分にREPインスタンスのデータファイル全体でいくつかの自動拡張イベントを確認できます。合計で512 MBで330の自動成長イベントがあり、合計168 GBでした。

Tempdbでこのスペースを何が使用したかを強調するのは困難ですが、Tempdbをこの方法で現在使用している可能性があるプロセスを知っていますか?

/------------------------------------------ ------------------\

自動拡張イベントが発生した頻度の特定

SQL Serverが自動拡張イベントを実行する場合、自動拡張イベントをトリガーしたトランザクションは、自動拡張イベントが完了するまで待機してからでないと、トランザクションを完了できません。これらの自動拡張イベントにより、自動拡張イベントが発生しているときにパフォーマンスが少し低下します。このため、データベースのサイズを適切に設定して、自動拡張イベントがほとんど発生しないようにすることが最善です。

システムで自動拡張イベントが発生する頻度に関心がある場合は、トレースを使用してそれらのイベントをキャプチャできます。自動拡張イベントを実行しているデータベースを把握することで、データベースファイルの拡張プロパティを調整して、自動拡張イベントの実行頻度を減らすことができます。プロファイラーの「データファイルの自動拡張」イベントや「ログファイルの自動拡張」イベントを使用して、これらのデータベースの自動拡張イベントを追跡できます。 SQL Server 2005以降を実行している場合、これらの自動拡張イベントは両方とも、デフォルトのトレースによってすでにキャプチャされています。デフォルトのトレースをオフにしていない場合は、デフォルトのトレースファイルを使用して、これらの自動拡張イベントを見つけることができます。デフォルトのトレースをオフにしている場合は、それを有効にするか、「データファイルの自動拡張」および「ログファイルの自動拡張」イベントをキャプチャする新しいプロファイラートレースを設定できます。

デフォルトのトレースはファイルに記録します。リスト4のコードは、デフォルトのトレースファイルからすべての自動拡張イベントを抽出する方法を示しています。独自のプロファイラートレースセッションを作成してこれらの自動拡張イベントをキャプチャする場合は、プロファイラートレース設定を満たすようにこのスクリプトを変更する必要があります。

https://www.simple-talk.com/sql/database-administration/sql-server-database-growth-and-autogrowth-settings/

マルセロミオレッリ2014年3月11日

\*--------------------------------------------------*/
DECLARE @filename NVARCHAR(1000);
DECLARE @bc INT;
DECLARE @ec INT;
DECLARE @bfn VARCHAR(1000);
DECLARE @efn VARCHAR(10);

-- Get the name of the current default trace
SELECT @filename = CAST(value AS NVARCHAR(1000))
FROM ::fn_trace_getinfo(DEFAULT)
WHERE traceid = 1 AND property = 2;

-- rip apart file name into pieces
SET @filename = REVERSE(@filename);
SET @bc = CHARINDEX('.',@filename);
SET @ec = CHARINDEX('_',@filename)+1;
SET @efn = REVERSE(SUBSTRING(@filename,1,@bc));
SET @bfn = REVERSE(SUBSTRING(@filename,@ec,LEN(@filename)));

-- set filename without rollover number
SET @filename = @bfn + @efn

-- process all trace files
SELECT 
  ftg.StartTime
,te.name AS EventName
,DB_NAME(ftg.databaseid) AS DatabaseName  
,ftg.Filename
,(ftg.IntegerData*8)/1024.0 AS GrowthMB 
,(ftg.duration/1000)AS DurMS
FROM ::fn_trace_gettable(@filename, DEFAULT) AS ftg 
INNER JOIN sys.trace_events AS te ON ftg.EventClass = te.trace_event_id  
WHERE (ftg.EventClass = 92  -- Date File Auto-grow
    OR ftg.EventClass = 93) -- Log File Auto-grow
ORDER BY ftg.StartTime
3

自動成長の原因となったプロセスを見つける唯一の方法は、拡張イベント(特に)を使用することです。 EVENT-> sqlserver.database_file_size_changesqlserver.databases_log_file_size_changedおよびACTION-> sqlserver.sql_text

@ DBA_ANDYはすでにXEventを作成するためのハードワークを実行しました

-- Original Author : @DBA_ANDY http://nebraskasql.blogspot.com/2016/06/finding-file-growths-with-extended.html
-- Modified by : Kin to filter on tempdb autogrowth events
SET NOCOUNT ON 
/* Create Extended Events Session */
IF EXISTS (SELECT 1 FROM master.sys.server_event_sessions WHERE name = 'DemoFileSize')
 DROP EVENT SESSION [DemoFileSize] ON SERVER
GO
CREATE EVENT SESSION [DemoFileSize] ON SERVER
ADD EVENT sqlserver.database_file_size_change(SET collect_database_name=(1)
    ACTION(package0.collect_system_time,sqlos.task_time,
 sqlserver.client_app_name,sqlserver.client_hostname,
 sqlserver.client_pid,sqlserver.database_id,sqlserver.database_name,
 sqlserver.server_instance_name,sqlserver.session_id,
 sqlserver.sql_text,sqlserver.username)
 WHERE ( [database_id] = ( 2 ) -- This is tempdb database id
),
 /* Note -  predicate/filter - will collect only for tempdb */
ADD EVENT sqlserver.databases_log_file_size_changed(
    ACTION(package0.collect_system_time,sqlos.task_time,
 sqlserver.client_app_name,sqlserver.client_hostname,
 sqlserver.client_pid,sqlserver.database_id,sqlserver.database_name,
 sqlserver.server_instance_name,sqlserver.session_id,
 sqlserver.sql_text,sqlserver.username)
 WHERE ( [database_id] = ( 2 ) -- This is tempdb database id
  )
 /* Note -  predicate/filter - will collect only for tempdb */
ADD TARGET package0.event_file(SET filename=N'D:\XEvent_logs\DemoFileSize.xel',-- change HERE !!
 max_file_size=(500),max_rollover_files=(10))
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=OFF,STARTUP_STATE=ON)
GO

ALTER EVENT SESSION [DemoFileSize] ON SERVER
STATE = START;
GO

xEvent xmlを細断処理します...

SELECT
Case when file_type = 'Data file' Then 'Data File Grow' Else File_Type End AS [Event Name]
, database_name AS DatabaseName
, dateadd(minute, datediff(minute, sysutcdatetime(), sysdatetime()), timestamp1) as LocalTimeStamp
/* added the timestamp and in XE is UTC - this code converts it to local server time zone */
, file_names
, size_change_mb
, duration
, client_app_name AS Client_Application
, client_hostname
, session_id AS SessionID
, sql_txt   ----------------> This is the process TSQL text !
, sql_username
, Is_Automatic

FROM
(
SELECT
(n.value ('(data[@name="size_change_kb"]/value)[1]', 'int')/1024.0) AS size_change_mb
, n.value('(@timestamp)[1]', 'datetime2') as timestamp1
, n.value ('(data[@name="database_name"]/value)[1]', 'nvarchar(50)') AS database_name
, n.value ('(data[@name="duration"]/value)[1]', 'int') AS duration
, n.value ('(data[@name="file_type"]/text)[1]','nvarchar(50)') AS file_type
, n.value ('(action[@name="client_app_name"]/value)[1]','nvarchar(50)') AS client_app_name
, n.value ('(action[@name="session_id"]/value)[1]','nvarchar(50)') AS session_id
, n.value ('(action[@name="client_hostname"]/value)[1]','nvarchar(50)') AS Client_HostName
, n.value ('(data[@name="file_name"]/value)[1]','nvarchar(50)') AS file_names
, n.value ('(data[@name="is_automatic"]/value)[1]','nvarchar(50)') AS Is_Automatic
, n.value ('(action[@name="sql_text"]/value)[1]','nvarchar(500)') AS sql_txt
, n.value ('(action[@name="username"]/value)[1]','nvarchar(50)') AS sql_username

FROM
(
SELECT CAST(event_data AS XML) AS event_data
FROM sys.fn_xe_file_target_read_file(
N'D:\XEvent_logs\DemoFileSize*.xel' -- CHANGE HERE !!
, NULL
, NULL
, NULL
)
) AS Event_Data_Table
CROSS APPLY event_data.nodes('event') AS q(n)) xyz
ORDER BY timestamp1 desc

以下は出力です:

enter image description here 重要なこと:

4
Kin Shah