Is there a way to look at the complete history of growth and shrink
events for the last weeks/months on SQL Server 2014
Yes there is a way, or should i say various ways to save the data collected from default trace as explained here Collecting the Information in the Default Trace
- We could query the default trace files and save aggregated values
- We could get the definition of the default trace and create a
collection set, which can be used with Management Data Warehouse,
which is built in with SQL Server.
- We could get the definition of the default trace and create a remote
trace from another server and save the data to a database table
- We could use a robocopy script to copy the trace files from our
server to a different folder or a remote machine, which will leave
the files on disk for longer time, giving us the possibility to
analyze them
Came up with below query, but it doesn't show any of the "manual"
log shrink events, just the "auto" events. Am I doing this the wrong
way, any other place to look for past info ?To capture the manual shrink events i use query like below:
SELECT
TextData,
HostName,
ApplicationName,
LoginName,
StartTime
FROM
[fn_trace_gettable]('C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Log\log_75.trc', DEFAULT)
WHERE TextData LIKE '%SHRINKFILE%'; ----- Location of default trace will be different ,so kindly check that accordingly
Probable reason you're query does not display manual grow or shrink events because you use events like (93, 95) which are for auto grow events
The only way to find out what process caused the autogrowth is to use Extended events esp. EVENT
--> sqlserver.database_file_size_change
& sqlserver.databases_log_file_size_changed
and ACTION
--> sqlserver.sql_text
.
Looks like @DBA_ANDY already did the hard work of writing an 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
shred the 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
Below is the output:
Important things :
Best Answer
You may not have a dramatic slow down if you have Instant File Initialization turned on for data growths, but the log will still suspend activity while it grows. You can insert rows into a demo table via a while loop and track the number of seconds required for the insert.