I bring you yet another installment in the monthly meme called T-SQL Tuesday. This is the 67th edition, and this time we have been given the opportunity to talk about something I really enjoy – Extended Events.
Props to Jes Borland (blog | twitter) for picking such an awesome topic. There is so much to cover with extended events, it’s like a green canvas ready for anything you can imagine.
Birkenstocks?
I will save the explanation here for later when hopefully it all ties together for you (well, at least buckles up).
While that is all fun and playful, let’s get down to the serious side now. One of my favorite quick fixes as a consultant is to come in and find that the server is set to “environment friendly” / “green” / “treehugger” mode. You can read more about power saving cpus from my friend Wayne Sheffield here.
That poor old cpu thing has been beat up pretty good. But how can we tell if the server is running in that mode if the only thing we can do is look in SQL Server (can’t install cpu-z, or don’t have adequate permissions on the server to see windows settings – just play along)? Lucky for us there is this cool thing called Extended Events.
In SQL Server we have this cool event called perfobject_processor. This particular event has some really cool metrics that it captures. One such metric is the frequency. The frequency is an indicator to us whether the server has the cpu set to balanced, high performance, or power saver. Having that in mind, let’s create a session to trap this data and experiment a little with the cpu settings.
USE master; GO -- Create the Event Session IF EXISTS ( SELECT * FROM sys.server_event_sessions WHERE name = 'TreeHuggerCPU' ) DROP EVENT SESSION TreeHuggerCPU ON SERVER; GO EXECUTE xp_create_subdir 'C:\Database\XE'; GO CREATE EVENT SESSION TreeHuggerCPU ON SERVER ADD EVENT sqlserver.perfobject_processor ( ACTION ( sqlos.cpu_id, sqlos.numa_node_id, package0.collect_cpu_cycle_time, sqlserver.server_instance_name, package0.collect_system_time ) --WHERE sqlserver.client_app_name <> 'Microsoft SQL Server Management Studio - Transact-SQL IntelliSense' ) ADD TARGET package0.event_file ( SET filename = N'C:\Database\XE\TreeHuggerCPU.xel' ); /* start the session */ALTER EVENT SESSION TreeHuggerCPU ON SERVER STATE = START; GO
Well, that looks amazingly easy and straight forward. I am telling the session to trap the additional CPU information such as numa_node_id and cpu_id. You can eliminate those if you wish. They may be beneficial when trying to identify if there is an issue on a specific processor though.
To experiment, I will break out the age old argument provoker – xp_cmdshell. I will use that to cycle through each of the power saving settings and look at the results. Here is the bulk of the script all together.
EXEC sp_configure 'show advanced options', 1; GO RECONFIGURE WITH OVERRIDE; GO EXEC sp_configure 'xp_cmdshell', 1; GO RECONFIGURE WITH OVERRIDE; GO --max power saving EXECUTE xp_cmdshell 'powercfg -SETACTIVE SCHEME_MAX'; GO --now look at the XE --balanced power saving EXECUTE xp_cmdshell 'powercfg -SETACTIVE SCHEME_BALANCED'; --now look at the XE --min power saving EXECUTE xp_cmdshell 'powercfg -SETACTIVE SCHEME_MIN'; --now look at the XE
And now for the XE Parser.
USE master; GO SELECT event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name , event_data.value('(event/@timestamp)[1]', 'varchar(50)') AS [TIMESTAMP] , event_data.value('(event/action[@name="server_instance_name"]/value)[1]', 'varchar(max)') AS ServerInstance , event_data.value('(event/action[@name="numa_node_id"]/value)[1]', 'varchar(max)') AS NUMANodeID , event_data.value('(event/action[@name="cpu_id"]/value)[1]', 'varchar(max)') AS CPUID , event_data.value('(event/action[@name="collect_cpu_cycle_time"]/value)[1]', 'varchar(max)') AS CPUCycleTime , event_data.value('(event/action[@name="collect_system_time"]/value)[1]', 'varchar(max)') AS SystemTime , event_data.value('(event/data[@name="parking_status"]/value)[1]', 'varchar(max)') AS ProcessorParkStatus , event_data.value('(event/data[@name="processor_frequency"]/value)[1]', 'varchar(max)') AS ProcessorFrequency , event_data.value('(event/data[@name="percent_maximum_frequency"]/value)[1]', 'varchar(max)') AS PercentMaxProcessorFrequency , event_data.value('(event/data[@name="processor_state_flags"]/value)[1]', 'varchar(max)') AS ProcessorState , event_data.value('(event/data[@name="instance_name"]/value)[1]', 'varchar(max)') AS CPUInstance FROM ( SELECT CONVERT(XML, t2.event_data) AS event_data FROM ( SELECT target_data = CONVERT(XML, target_data) FROM sys.dm_xe_session_targets t INNER JOIN sys.dm_xe_sessions s ON t.event_session_address = s.address WHERE t.target_name = 'event_file' AND s.name = 'TreeHuggerCPU' ) cte1 CROSS APPLY cte1.target_data.nodes('//EventFileTarget/File') FileEvent ( FileTarget ) CROSS APPLY sys.fn_xe_file_target_read_file(FileEvent.FileTarget.value('@name', 'varchar(1000)'), NULL, NULL, NULL) t2 ) AS evts ( event_data );
If I parse through the extended event after each change of the power scheme, I would be able to see the effect of each scheme change in the event session as well as in a tool such as Resource Monitor. Here is what I was able to see with each of the changes.
Balanced Saver
From Resource Monitor:
And the XE data:
This is my default power scheme. On my laptop, this is ok. For a production SQL server, this will cause problems.
High Performance
Quickly, you should be able to spot that the blue line in the graph, and the numeric values from the XE session correlate to the processor giving you everything it has. This is good for SQL Server.
Power Saver
See how that blue line falls off sharply?
Supporting that steep fall in the graph, we can see that the XE trapped the percent of max frequency as 36%. You might be lucky and attain 36%. Don’t be surprised if you see something even lower. Please don’t use this setting on a production box – unless you want to go bald.
We can see that we have great tools via Extended Events to help troubleshoot various problems. As I said, this is one of my favorites because it is a very common problem and a very easy fix.
SQL Server is not GREEN! Do not put birkenstocks on the server and try to turn the server into a tree hugger. It just won’t work out that well. Set your fileservers or your print servers to be more power conscientious, but this is something that will not work well on SQL Server.
Final thought. If you have not figured out the birkenstocks, well it is a common stereotype with environmentalists in some areas that they may wear woolly socks and birkenstocks.
No wool socks were harmed in the making of this blog post!