Files
sql-scripts/TPDT-268 - ACP in task sequence/dba_packages/deployMonitorWaitStats.sql
2024-03-07 16:52:14 +01:00

572 lines
19 KiB
Transact-SQL

USE [HCITools];
GO
/*=============================================================================
Collect les stats des wait sur l'instance locale et les stocks en db
-----------------------------------------------
Afin de surveiller l'évolution des wait stats, cette proc collecte les infos des wait stats dans la table hciTools.dbo.[Monitor_wait_stats]
depuis le démarrage du serveur ou le dernier effacement des stats.
Contexte d'utilisation
----------------------
Sur toute instance triapharm sauf les POS
Création : 11.10.2022 / TSC
=============================================================================*/
GO
SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
GO
/* Creation de la table, si nécessaire*/
IF OBJECT_ID('dbo.Monitor_wait_stats') IS NULL
BEGIN
CREATE TABLE [dbo].[Monitor_wait_stats]
(
[Monitor_wait_stats_ID] [BIGINT] IDENTITY(1, 1) NOT NULL,
[MWS_wait_type] [NVARCHAR](60) NOT NULL,
[MWS_wait_time_s] [DECIMAL](14, 2) NOT NULL,
[MWS_resource_time_s] [DECIMAL](14, 2) NOT NULL,
[MWS_signal_time_s] [DECIMAL](14, 2) NOT NULL,
[MWS_wait_count] [BIGINT] NOT NULL,
[MWS_percentage] [DECIMAL](5, 2) NOT NULL,
[MWS_avg_wait_time_sec] [DECIMAL](14, 4) NOT NULL,
[MWS_avg_resource_time_s] [DECIMAL](14, 4) NOT NULL,
[MWS_avg_signal_time_s] [DECIMAL](14, 4) NOT NULL,
[MWS_sql_server_name] [NVARCHAR](128) NOT NULL,
[MWS_sql_server_start_date] [DATETIME] NOT NULL,
[MWS_value_date] [DATETIME] NOT NULL,
[MWS_remark] [VARCHAR](MAX) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY];
ALTER TABLE [dbo].[Monitor_wait_stats]
ADD
DEFAULT (GETDATE()) FOR [MWS_value_date];
END;
/* adaptation de la table pour permettre l'enregistrement de 100 % */
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Monitor_wait_stats' AND COLUMN_NAME = 'MWS_percentage' AND [NUMERIC_PRECISION] = 4)
BEGIN
ALTER TABLE [dbo].[Monitor_wait_stats] ALTER COLUMN [MWS_percentage] [DECIMAL](5, 2) NOT NULL;
END
/*proc mon_collect_wait_stats*/
IF OBJECT_ID('dbo.mon_collect_wait_stats') IS NOT NULL
BEGIN
DROP PROCEDURE dbo.mon_collect_wait_stats;
END;
GO
/*=============================================================================
Collect wait stats
-----------------------------------------------
US OCTPDBA-336
Collect and store wait stats into hciTools.dbo.Monitor_wait_stats
Derived from http://www.sqlskills.com/blogs/paul/wait-statistics-or-please-tell-me-where-it-hurts/
Contexte d'utilisation
----------------------
Job : [D92060 - Monitor Wait Stats]
Création : 11.10.2022 / TSC
=============================================================================*/
CREATE PROCEDURE dbo.mon_collect_wait_stats
AS
BEGIN
SET XACT_ABORT OFF;
SET NOCOUNT ON;
WITH [Waits]
AS (SELECT
[wait_type],
[wait_time_ms] / 1000.0 AS [WaitS],
([wait_time_ms] - [signal_wait_time_ms]) / 1000.0 AS [ResourceS],
[signal_wait_time_ms] / 1000.0 AS [SignalS],
[waiting_tasks_count] AS [WaitCount],
100.0 * [wait_time_ms] / SUM([wait_time_ms]) OVER () AS [Percentage],
ROW_NUMBER() OVER (ORDER BY [wait_time_ms] DESC) AS [RowNum]
FROM sys.dm_os_wait_stats
WHERE [wait_type] NOT IN ( N'BROKER_EVENTHANDLER', N'BROKER_RECEIVE_WAITFOR', N'BROKER_TASK_STOP',
N'BROKER_TO_FLUSH', N'BROKER_TRANSMITTER', N'CHECKPOINT_QUEUE', N'CHKPT',
N'CLR_AUTO_EVENT', N'CLR_MANUAL_EVENT', N'CLR_SEMAPHORE', N'DBMIRROR_DBM_EVENT',
N'DBMIRROR_EVENTS_QUEUE', N'DBMIRROR_WORKER_QUEUE', N'DBMIRRORING_CMD',
N'DIRTY_PAGE_POLL', N'DISPATCHER_QUEUE_SEMAPHORE', N'EXECSYNC', N'FSAGENT',
N'FT_IFTS_SCHEDULER_IDLE_WAIT', N'FT_IFTSHC_MUTEX', N'HADR_CLUSAPI_CALL',
N'HADR_FILESTREAM_IOMGR_IOCOMPLETION', N'HADR_LOGCAPTURE_WAIT',
N'HADR_NOTIFICATION_DEQUEUE', N'HADR_TIMER_TASK', N'HADR_WORK_QUEUE',
N'KSOURCE_WAKEUP', N'LAZYWRITER_SLEEP', N'LOGMGR_QUEUE', N'ONDEMAND_TASK_QUEUE',
N'PWAIT_ALL_COMPONENTS_INITIALIZED', N'QDS_PERSIST_TASK_MAIN_LOOP_SLEEP',
N'QDS_CLEANUP_STALE_QUERIES_TASK_MAIN_LOOP_SLEEP', N'REQUEST_FOR_DEADLOCK_SEARCH',
N'RESOURCE_QUEUE', N'SERVER_IDLE_CHECK', N'SLEEP_BPOOL_FLUSH', N'SLEEP_DBSTARTUP',
N'SLEEP_DCOMSTARTUP', N'SLEEP_MASTERDBREADY', N'SLEEP_MASTERMDREADY',
N'SLEEP_MASTERUPGRADED', N'SLEEP_MSDBSTARTUP', N'SLEEP_SYSTEMTASK', N'SLEEP_TASK',
N'SLEEP_TEMPDBSTARTUP', N'SNI_HTTP_ACCEPT', N'SP_SERVER_DIAGNOSTICS_SLEEP',
N'SQLTRACE_BUFFER_FLUSH', N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
N'SQLTRACE_WAIT_ENTRIES', N'WAIT_FOR_RESULTS', N'WAITFOR', N'WAITFOR_TASKSHUTDOWN',
N'WAIT_XTP_HOST_WAIT', N'WAIT_XTP_OFFLINE_CKPT_NEW_LOG', N'WAIT_XTP_CKPT_CLOSE',
N'XE_DISPATCHER_JOIN', N'XE_DISPATCHER_WAIT', N'XE_TIMER_EVENT'
)
AND [waiting_tasks_count] > 0)
INSERT INTO [HCITools].[dbo].[Monitor_wait_stats]
(
[MWS_wait_type],
[MWS_wait_time_s],
[MWS_resource_time_s],
[MWS_signal_time_s],
[MWS_wait_count],
[MWS_percentage],
[MWS_avg_wait_time_sec],
[MWS_avg_resource_time_s],
[MWS_avg_signal_time_s],
[MWS_sql_server_name],
[MWS_sql_server_start_date],
[MWS_value_date]
)
SELECT
MAX([W1].[wait_type]) AS MWS_wait_type,
CAST(MAX([W1].[WaitS]) AS DECIMAL(14, 2)) AS MWS_wait_time_s,
CAST(MAX([W1].[ResourceS]) AS DECIMAL(14, 2)) AS MWS_resource_time_s,
CAST(MAX([W1].[SignalS]) AS DECIMAL(14, 2)) AS MWS_signal_time_s,
MAX([W1].[WaitCount]) AS MWS_wait_count,
CAST(MAX([W1].[Percentage]) AS DECIMAL(5, 2)) AS MWS_percentage,
CAST(MAX([W1].[WaitS]) / ISNULL(NULLIF(MAX([W1].[WaitCount]), 0),1) AS DECIMAL(14, 4)) AS MWS_avg_wait_time_sec,
CAST(MAX([W1].[ResourceS]) / ISNULL(NULLIF(MAX([W1].[WaitCount]), 0),1) AS DECIMAL(14, 4)) AS MWS_avg_resource_time_s,
CAST(MAX([W1].[SignalS]) / ISNULL(NULLIF(MAX([W1].[WaitCount]), 0),1) AS DECIMAL(14, 4)) AS MWS_avg_signal_time_s,
@@SERVERNAME AS MWS_sql_server_name,
(SELECT sqlserver_start_time FROM sys.dm_os_sys_info) AS MWS_sql_server_start_date,
GETDATE() AS MWS_value_date
FROM [Waits] AS [W1]
INNER JOIN [Waits] AS [W2]
ON [W2].[RowNum] <= [W1].[RowNum]
GROUP BY [W1].[RowNum]
HAVING SUM([W2].[Percentage]) - MAX([W1].[Percentage]) < 99; --percentage threshold
END
GO
/*proc mon_clear_wait_stats*/
IF OBJECT_ID('dbo.mon_clear_wait_stats') IS NOT NULL
BEGIN
DROP PROCEDURE dbo.mon_clear_wait_stats
END
GO
/*=============================================================================
Clear wait stats
-----------------------------------------------
US OCTPDBA-336
Clear the current wait stats from the local instance
Contexte d'utilisation
----------------------
Job : [D92060 - Monitor Wait Stats]
Création : 11.10.2022 / TSC
=============================================================================*/
CREATE PROCEDURE dbo.mon_clear_wait_stats
AS
BEGIN
SET XACT_ABORT OFF;
SET NOCOUNT ON;
DBCC SQLPERF('sys.dm_os_wait_stats',CLEAR)
END
GO
/*proc mon_purge_recorded_wait_stats*/
IF OBJECT_ID('dbo.mon_purge_recorded_wait_stats') IS NOT NULL
BEGIN
DROP PROCEDURE dbo.mon_purge_recorded_wait_stats
END
GO
/*=============================================================================
Purge recorded wait stats from [HCITools].[dbo].[Monitor_wait_stats]
-----------------------------------------------
US OCTPDBA-336
Purge the recorded wait stats from [HCITools].[dbo].[Monitor_wait_stats]
Contexte d'utilisation
----------------------
Job : [D92060 - Monitor Wait Stats]
Création : 11.10.2022 / TSC
=============================================================================*/
CREATE PROCEDURE dbo.mon_purge_recorded_wait_stats
@in_days_to_keep INT = 90 --how many days of history should be kept. default to 90 days (3 months)
AS
BEGIN
SET XACT_ABORT OFF;
SET NOCOUNT ON;
DECLARE @countDeletes INT = 1;
WHILE ISNULL(@countDeletes, 0) > 0
BEGIN
DELETE TOP(10000) FROM [HCITools].[dbo].[Monitor_wait_stats]
WHERE [MWS_value_date] <= DATEADD(DAY, @in_days_to_keep * -1, CURRENT_TIMESTAMP);
SET @countDeletes = @@ROWCOUNT;
END
END
GO
/* cleanup of previously defined jobs */
--SET XACT_ABORT ON;
--SET NOCOUNT ON;
--DECLARE @found_jobs_names TABLE (job_name VARCHAR(500) NOT NULL);
--INSERT INTO @found_jobs_names ([job_name])
--VALUES ('DR92060 - Monitor Wait Stats - Central'),
-- ('ZZ-LPE-Monitor Wait Stats'),
-- ('ZZ-LPE-Monitor Wait Stats - AMAREP'),
-- ('ZZ-LPE-Monitor Wait Stats - AMA051'),
-- ('ZZ-LPE-Monitor Wait Stats - AMA562'),
-- ('ZZ-LPE-Monitor Wait Stats - AMA603');
--/* declare variables */
--DECLARE @job_name VARCHAR(500);
--DECLARE clean_jobs CURSOR FAST_FORWARD READ_ONLY READ_ONLY FOR
--SELECT job_name
-- FROM @found_jobs_names;
--OPEN clean_jobs;
--FETCH NEXT FROM clean_jobs
-- INTO @job_name;
--WHILE @@FETCH_STATUS = 0
--BEGIN
-- IF EXISTS ( SELECT 1
-- FROM msdb.dbo.sysjobs sj
-- WHERE LOWER(sj.[name]) = LOWER(@job_name))
-- BEGIN
-- RAISERROR(
-- 'found job "%s". Dropping',
-- 1,
-- 1,
-- @job_name) WITH NOWAIT;
-- EXEC msdb.dbo.sp_delete_job @job_name = @job_name,
-- @delete_unused_schedule = 1;
-- END;
-- FETCH NEXT FROM clean_jobs
-- INTO @job_name;
--END;
--CLOSE clean_jobs;
--DEALLOCATE clean_jobs;
--GO
/*job et schedule*/
---- Drop _D... job and schedule, the job was renamed
/* Drop existing standard schedule for job */
DECLARE @schedule_id INT
DECLARE c_schedules CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY FOR
SELECT ss.schedule_id
FROM msdb.dbo.sysjobschedules sjs
INNER JOIN msdb.dbo.sysschedules ss
ON sjs.schedule_id = ss.schedule_id
AND ss.name NOT LIKE '%#SPEC#'
INNER JOIN msdb.dbo.sysjobs sj
ON sjs.job_id = sj.job_id
WHERE sj.name = N'_D92060 - Monitor Wait Stats'
OPEN c_schedules
FETCH NEXT FROM c_schedules INTO @schedule_id
WHILE @@fetch_status = 0
BEGIN
IF ((SELECT COUNT(*) FROM msdb.dbo.sysjobschedules WHERE schedule_id=@schedule_id) = 1)
EXEC msdb.dbo.sp_delete_schedule @schedule_id=@schedule_id, @force_delete = 1
FETCH NEXT FROM c_schedules INTO @schedule_id
END
CLOSE c_schedules
DEALLOCATE c_schedules
IF EXISTS (SELECT job_id FROM msdb.dbo.sysjobs_view WHERE name = N'_D92060 - Monitor Wait Stats')
EXEC msdb.dbo.sp_delete_job @job_name = N'_D92060 - Monitor Wait Stats', @delete_unused_schedule=0
GO
---Actual job is scripted starting here
declare @schedule_id int
declare c_schedules cursor local forward_only static READ_ONLY FOR
select ss.schedule_id
from msdb.dbo.sysjobschedules sjs
INNER JOIN msdb.dbo.sysschedules ss
ON sjs.schedule_id = ss.schedule_id
AND ss.name NOT LIKE '%#SPEC#'
INNER JOIN msdb.dbo.sysjobs sj
ON sjs.job_id = sj.job_id
WHERE sj.name = N'D92060 - Monitor Wait Stats'
open c_schedules
FETCH NEXT FROM c_schedules into @schedule_id
while @@fetch_status = 0
begin
IF ((select COUNT(*) from msdb.dbo.sysjobschedules where schedule_id=@schedule_id) = 1)
EXEC msdb.dbo.sp_delete_schedule @schedule_id=@schedule_id, @force_delete = 1
FETCH NEXT FROM c_schedules into @schedule_id
end
close c_schedules
deallocate c_schedules
IF EXISTS (SELECT job_id FROM msdb.dbo.sysjobs_view WHERE name = N'D92060 - Monitor Wait Stats')
EXEC msdb.dbo.sp_delete_job @job_name = N'D92060 - Monitor Wait Stats', @delete_unused_schedule=0
GO
/* Creation Job and Steps*/
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
END
/* Add Job */
DECLARE @jobId BINARY(16)
EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'D92060 - Monitor Wait Stats',
@enabled=0,
@notify_level_eventlog=0,
@notify_level_email=0,
@notify_level_netsend=0,
@notify_level_page=0,
@delete_level=0,
@description=N'Collect les stats des wait sur l''instance locale et les stocks en db
-----------------------------------------------
Afin de surveiller l''évolution des wait stats, cette proc collecte les infos des wait stats dans la table hciTools.dbo.[Monitor_wait_stats]
depuis le démarrage du serveur ou le dernier effacement des stats.
Contexte d''utilisation
----------------------
Sur toute instance triapharm sauf les POS
Création : 11.10.2022 / TSC',
@category_name=N'[Uncategorized (Local)]',
@start_step_id=1,
@owner_login_name=N'sa', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/* Add Step */
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'empty step',
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=3,
@on_success_step_id=0,
@on_fail_action=3,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'/* empty step */',
@database_name=N'master',
@output_file_name=NULL,
@flags=0,
@database_user_name=NULL,
@server=NULL,
@additional_parameters=NULL,
@proxy_id=NULL,
@proxy_name=NULL
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/* Add Step */
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Collect wait stats',
@step_id=2,
@cmdexec_success_code=0,
@on_success_action=3,
@on_success_step_id=0,
@on_fail_action=4,
@on_fail_step_id=6,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'exec dbo.mon_collect_wait_stats',
@database_name=N'HCITools',
@output_file_name=NULL,
@flags=0,
@database_user_name=NULL,
@server=NULL,
@additional_parameters=NULL,
@proxy_id=NULL,
@proxy_name=NULL
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/* Add Step */
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Clear wait stats',
@step_id=3,
@cmdexec_success_code=0,
@on_success_action=3,
@on_success_step_id=0,
@on_fail_action=4,
@on_fail_step_id=6,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'exec dbo.mon_clear_wait_stats',
@database_name=N'HCITools',
@output_file_name=NULL,
@flags=0,
@database_user_name=NULL,
@server=NULL,
@additional_parameters=NULL,
@proxy_id=NULL,
@proxy_name=NULL
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/* Add Step */
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Clean Wait Statistics history',
@step_id=4,
@cmdexec_success_code=0,
@on_success_action=3,
@on_success_step_id=0,
@on_fail_action=4,
@on_fail_step_id=6,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'exec dbo.mon_purge_recorded_wait_stats @in_days_to_keep = 90;',
@database_name=N'HCITools',
@output_file_name=NULL,
@flags=0,
@database_user_name=NULL,
@server=NULL,
@additional_parameters=NULL,
@proxy_id=NULL,
@proxy_name=NULL
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/* Add Step */
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'empty step for success',
@step_id=5,
@cmdexec_success_code=0,
@on_success_action=1,
@on_success_step_id=0,
@on_fail_action=4,
@on_fail_step_id=6,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'exec dbo.Get_Job_Error_Info @in_JobName = ''D92060 - Monitor Wait Stats'', @in_Recipients = ''DBA_operator''
',
@database_name=N'HCITools',
@output_file_name=NULL,
@flags=0,
@database_user_name=NULL,
@server=NULL,
@additional_parameters=NULL,
@proxy_id=NULL,
@proxy_name=NULL
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/* Add Step */
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'send email ko',
@step_id=6,
@cmdexec_success_code=0,
@on_success_action=2,
@on_success_step_id=0,
@on_fail_action=2,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'exec aps_Send_Mail_with_template
@in_param_varchar_2 = ''DBA_operator''
exec dbo.Get_Job_Error_Info @in_JobName = ''D92060 - Monitor Wait Stats'', @in_Recipients = ''DBA_operator''',
@database_name=N'HCITools',
@output_file_name=NULL,
@flags=0,
@database_user_name=NULL,
@server=NULL,
@additional_parameters=NULL,
@proxy_id=NULL,
@proxy_name=NULL
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/* Add Standard Schedule */
EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'D92060-D',
@enabled=1,
@freq_type=4,
@freq_interval=1,
@freq_subday_type=4,
@freq_subday_interval=5,
@freq_relative_interval=0,
@freq_recurrence_factor=0,
@active_start_date=20221012,
@active_end_date=99991231,
@active_start_time=0,
@active_end_time=235959
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/* Attach existing specific schedule for job */
declare @enabled_schedule int,
@schedule_name nvarchar(50)
declare c_schedules cursor local forward_only static for
select enabled, name
from msdb.dbo.sysschedules
where name LIKE 'D92060%'
and name LIKE '%#SPEC#'
open c_schedules
FETCH NEXT FROM c_schedules into @enabled_schedule, @schedule_name
while @@fetch_status = 0
begin
EXEC @ReturnCode = msdb.dbo.sp_attach_schedule @job_id = @jobId, @schedule_name=@schedule_name
IF(@enabled_schedule = 1)
begin
SET @schedule_name = SUBSTRING(@schedule_name,0,LEN(@schedule_name)-5)
IF EXISTS (select name from msdb.dbo.sysschedules where name = @schedule_name)
EXEC @ReturnCode = msdb.dbo.sp_update_schedule @name=@schedule_name, @enabled=0
end
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
FETCH NEXT FROM c_schedules into @enabled_schedule, @schedule_name
end
close c_schedules
deallocate c_schedules
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
GO