diff --git a/Dashboard/Helpers/ChartHoverHelper.cs b/Dashboard/Helpers/ChartHoverHelper.cs index bc46d80..17f2702 100644 --- a/Dashboard/Helpers/ChartHoverHelper.cs +++ b/Dashboard/Helpers/ChartHoverHelper.cs @@ -71,10 +71,9 @@ private void OnMouseMove(object sender, MouseEventArgs e) try { var pos = e.GetPosition(_chart); - var dpi = VisualTreeHelper.GetDpi(_chart); var pixel = new ScottPlot.Pixel( - (float)(pos.X * dpi.DpiScaleX), - (float)(pos.Y * dpi.DpiScaleY)); + (float)(pos.X * _chart.DisplayScale), + (float)(pos.Y * _chart.DisplayScale)); var mouseCoords = _chart.Plot.GetCoordinates(pixel); /* Use X-axis (time) proximity as the primary filter, Y-axis distance diff --git a/Installer/Program.cs b/Installer/Program.cs index aa91403..d16303a 100644 --- a/Installer/Program.cs +++ b/Installer/Program.cs @@ -95,7 +95,6 @@ static async Task Main(string[] args) Console.WriteLine(" -h, --help Show this help message"); Console.WriteLine(" --reinstall Drop existing database and perform clean install"); Console.WriteLine(" --reset-schedule Reset collection schedule to recommended defaults"); - Console.WriteLine(" --preserve-jobs Keep existing SQL Agent jobs (owner, schedule, notifications)"); Console.WriteLine(" --encrypt= Connection encryption: mandatory (default), optional, strict"); Console.WriteLine(" --trust-cert Trust server certificate without validation"); Console.WriteLine(); @@ -116,7 +115,6 @@ static async Task Main(string[] args) bool automatedMode = args.Length > 0; bool reinstallMode = args.Any(a => a.Equals("--reinstall", StringComparison.OrdinalIgnoreCase)); bool resetSchedule = args.Any(a => a.Equals("--reset-schedule", StringComparison.OrdinalIgnoreCase)); - bool preserveJobs = args.Any(a => a.Equals("--preserve-jobs", StringComparison.OrdinalIgnoreCase)); bool trustCert = args.Any(a => a.Equals("--trust-cert", StringComparison.OrdinalIgnoreCase)); /*Parse encryption option (default: Mandatory)*/ @@ -137,7 +135,6 @@ static async Task Main(string[] args) var filteredArgs = args .Where(a => !a.Equals("--reinstall", StringComparison.OrdinalIgnoreCase)) .Where(a => !a.Equals("--reset-schedule", StringComparison.OrdinalIgnoreCase)) - .Where(a => !a.Equals("--preserve-jobs", StringComparison.OrdinalIgnoreCase)) .Where(a => !a.Equals("--trust-cert", StringComparison.OrdinalIgnoreCase)) .Where(a => !a.StartsWith("--encrypt=", StringComparison.OrdinalIgnoreCase)) .ToArray(); @@ -656,16 +653,6 @@ INSERT...WHERE NOT EXISTS re-populates with current recommended values Console.Write("(resetting schedule) "); } - /* - Preserve existing SQL Agent jobs if requested — flip the T-SQL - variable so existing jobs are left untouched during upgrade - */ - if (preserveJobs && fileName.StartsWith("45_", StringComparison.Ordinal)) - { - sqlContent = sqlContent.Replace("@preserve_jobs bit = 0", "@preserve_jobs bit = 1"); - Console.Write("(preserving existing jobs) "); - } - /* Remove SQLCMD directives (:r includes) as we're executing files directly */ diff --git a/InstallerGui/MainWindow.xaml b/InstallerGui/MainWindow.xaml index 76e650d..61b4046 100644 --- a/InstallerGui/MainWindow.xaml +++ b/InstallerGui/MainWindow.xaml @@ -186,12 +186,6 @@ Margin="0,0,0,10" Foreground="{DynamicResource ForegroundBrush}"/> - - - { diff --git a/InstallerGui/Services/InstallationService.cs b/InstallerGui/Services/InstallationService.cs index 30e7b66..2935702 100644 --- a/InstallerGui/Services/InstallationService.cs +++ b/InstallerGui/Services/InstallationService.cs @@ -325,7 +325,6 @@ public static async Task ExecuteInstallationAsync( List sqlFiles, bool cleanInstall, bool resetSchedule = false, - bool preserveJobs = false, IProgress? progress = null, Func? preValidationAction = null, CancellationToken cancellationToken = default) @@ -423,17 +422,6 @@ Execute SQL files }); } - /*Preserve existing SQL Agent jobs if requested*/ - if (preserveJobs && fileName.StartsWith("45_", StringComparison.Ordinal)) - { - sqlContent = sqlContent.Replace("@preserve_jobs bit = 0", "@preserve_jobs bit = 1"); - progress?.Report(new InstallationProgress - { - Message = "Preserving existing SQL Agent jobs...", - Status = "Info" - }); - } - /*Remove SQLCMD directives*/ sqlContent = SqlCmdDirectivePattern.Replace(sqlContent, ""); diff --git a/Lite/Helpers/ChartHoverHelper.cs b/Lite/Helpers/ChartHoverHelper.cs index 80d51d2..207f374 100644 --- a/Lite/Helpers/ChartHoverHelper.cs +++ b/Lite/Helpers/ChartHoverHelper.cs @@ -69,10 +69,9 @@ private void OnMouseMove(object sender, MouseEventArgs e) _lastUpdate = now; var pos = e.GetPosition(_chart); - var dpi = VisualTreeHelper.GetDpi(_chart); var pixel = new ScottPlot.Pixel( - (float)(pos.X * dpi.DpiScaleX), - (float)(pos.Y * dpi.DpiScaleY)); + (float)(pos.X * _chart.DisplayScale), + (float)(pos.Y * _chart.DisplayScale)); var mouseCoords = _chart.Plot.GetCoordinates(pixel); double bestDistance = double.MaxValue; diff --git a/install/01_install_database.sql b/install/01_install_database.sql index 2d71820..db141d7 100644 --- a/install/01_install_database.sql +++ b/install/01_install_database.sql @@ -274,10 +274,6 @@ BEGIN DEFAULT 5, retention_days integer NOT NULL DEFAULT 30, - collect_query bit NOT NULL - DEFAULT CONVERT(bit, 'true'), - collect_plan bit NOT NULL - DEFAULT CONVERT(bit, 'true'), [description] nvarchar(500) NULL, created_date datetime2(7) NOT NULL DEFAULT SYSDATETIME(), diff --git a/install/08_collect_query_stats.sql b/install/08_collect_query_stats.sql index 6ae1471..b264867 100644 --- a/install/08_collect_query_stats.sql +++ b/install/08_collect_query_stats.sql @@ -107,16 +107,16 @@ BEGIN END; /* - First run detection - collect last 1 hour of queries if this is the first execution + First run detection - collect all queries if this is the first execution */ IF NOT EXISTS (SELECT 1/0 FROM collect.query_stats) AND NOT EXISTS (SELECT 1/0 FROM config.collection_log WHERE collector_name = N'query_stats_collector') BEGIN - SET @cutoff_time = DATEADD(HOUR, -1, SYSDATETIME()); + SET @cutoff_time = CONVERT(datetime2(7), '19000101'); IF @debug = 1 BEGIN - RAISERROR(N'First run detected - collecting last 1 hour of query stats', 0, 1) WITH NOWAIT; + RAISERROR(N'First run detected - collecting all queries from sys.dm_exec_query_stats', 0, 1) WITH NOWAIT; END; END; ELSE @@ -153,19 +153,6 @@ BEGIN RAISERROR(N'Collecting queries executed since %s', 0, 1, @cutoff_time_string) WITH NOWAIT; END; - /* - Read collection flags for query text and plans - */ - DECLARE - @collect_query bit = 1, - @collect_plan bit = 1; - - SELECT - @collect_query = cs.collect_query, - @collect_plan = cs.collect_plan - FROM config.collection_schedule AS cs - WHERE cs.collector_name = N'query_stats_collector'; - /* Collect query statistics directly from DMV Only collects queries executed since last collection @@ -268,8 +255,6 @@ BEGIN max_spills = qs.max_spills, query_text = CASE - WHEN @collect_query = 0 - THEN NULL WHEN qs.statement_start_offset = 0 AND qs.statement_end_offset = -1 THEN st.text @@ -287,12 +272,7 @@ BEGIN ) / 2 + 1 ) END, - query_plan_text = - CASE - WHEN @collect_plan = 1 - THEN tqp.query_plan - ELSE NULL - END + query_plan_text = tqp.query_plan FROM sys.dm_exec_query_stats AS qs OUTER APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st OUTER APPLY diff --git a/install/10_collect_procedure_stats.sql b/install/10_collect_procedure_stats.sql index fb72c94..7f8e411 100644 --- a/install/10_collect_procedure_stats.sql +++ b/install/10_collect_procedure_stats.sql @@ -107,16 +107,16 @@ BEGIN END; /* - First run detection - collect last 1 hour of procedures if this is the first execution + First run detection - collect all procedures if this is the first execution */ IF NOT EXISTS (SELECT 1/0 FROM collect.procedure_stats) AND NOT EXISTS (SELECT 1/0 FROM config.collection_log WHERE collector_name = N'procedure_stats_collector') BEGIN - SET @cutoff_time = DATEADD(HOUR, -1, SYSDATETIME()); + SET @cutoff_time = CONVERT(datetime2(7), '19000101'); IF @debug = 1 BEGIN - RAISERROR(N'First run detected - collecting last 1 hour of procedure stats', 0, 1) WITH NOWAIT; + RAISERROR(N'First run detected - collecting all procedures from sys.dm_exec_procedure_stats', 0, 1) WITH NOWAIT; END; END; ELSE @@ -153,17 +153,6 @@ BEGIN RAISERROR(N'Collecting procedure stats with cutoff time: %s', 0, 1, @cutoff_time_string) WITH NOWAIT; END; - /* - Read collection flag for plans - */ - DECLARE - @collect_plan bit = 1; - - SELECT - @collect_plan = cs.collect_plan - FROM config.collection_schedule AS cs - WHERE cs.collector_name = N'procedure_stats_collector'; - /* Collect procedure, trigger, and function statistics Single query with UNION ALL to collect from all three DMVs @@ -234,12 +223,7 @@ BEGIN total_spills = ps.total_spills, min_spills = ps.min_spills, max_spills = ps.max_spills, - query_plan_text = - CASE - WHEN @collect_plan = 1 - THEN CONVERT(nvarchar(max), tqp.query_plan) - ELSE NULL - END + query_plan_text = CONVERT(nvarchar(max), tqp.query_plan) FROM sys.dm_exec_procedure_stats AS ps OUTER APPLY sys.dm_exec_text_query_plan @@ -402,12 +386,7 @@ BEGIN total_spills = ts.total_spills, min_spills = ts.min_spills, max_spills = ts.max_spills, - query_plan_text = - CASE - WHEN @collect_plan = 1 - THEN CONVERT(nvarchar(max), tqp.query_plan) - ELSE NULL - END + query_plan_text = CONVERT(nvarchar(max), tqp.query_plan) FROM sys.dm_exec_trigger_stats AS ts CROSS APPLY sys.dm_exec_sql_text(ts.sql_handle) AS st OUTER APPLY @@ -467,12 +446,7 @@ BEGIN total_spills = NULL, min_spills = NULL, max_spills = NULL, - query_plan_text = - CASE - WHEN @collect_plan = 1 - THEN CONVERT(nvarchar(max), tqp.query_plan) - ELSE NULL - END + query_plan_text = CONVERT(nvarchar(max), tqp.query_plan) FROM sys.dm_exec_function_stats AS fs OUTER APPLY sys.dm_exec_text_query_plan diff --git a/install/18_collect_cpu_utilization_stats.sql b/install/18_collect_cpu_utilization_stats.sql index 6849a13..536ceca 100644 --- a/install/18_collect_cpu_utilization_stats.sql +++ b/install/18_collect_cpu_utilization_stats.sql @@ -112,7 +112,7 @@ BEGIN /* Collect CPU utilization data from ring buffers Only collects samples newer than the most recent sample we have - On first run (NULL max_sample_time), looks back 1 hour to populate initial data + On first run (NULL max_sample_time), looks back 7 days to populate initial data Avoids duplicate collection of same ring buffer events */ INSERT INTO @@ -156,7 +156,7 @@ BEGIN SECOND, -((@current_ms_ticks - t.timestamp) / 1000), @start_time - ) > ISNULL(@max_sample_time, DATEADD(HOUR, -1, @start_time)) + ) > ISNULL(@max_sample_time, DATEADD(DAY, -7, @start_time)) ORDER BY t.timestamp DESC OPTION(RECOMPILE); diff --git a/install/22_collect_blocked_processes.sql b/install/22_collect_blocked_processes.sql index 33e0e62..5032ad3 100644 --- a/install/22_collect_blocked_processes.sql +++ b/install/22_collect_blocked_processes.sql @@ -140,17 +140,17 @@ BEGIN END; /* - First run detection - collect last 1 hour of history if this is the first execution + First run detection - collect 3 days of history if this is the first execution */ IF NOT EXISTS (SELECT 1/0 FROM collect.blocked_process_xml) AND NOT EXISTS (SELECT 1/0 FROM config.collection_log WHERE collector_name = N'blocked_process_xml_collector') BEGIN - SET @minutes_back = 60; /*1 hour*/ + SET @minutes_back = 4320; /*3 days*/ SET @cutoff_time = DATEADD(MINUTE, -@minutes_back, SYSUTCDATETIME()); IF @debug = 1 BEGIN - RAISERROR(N'First run detected - collecting last 1 hour of blocked process events', 0, 1) WITH NOWAIT; + RAISERROR(N'First run detected - collecting last 3 days of blocked process events', 0, 1) WITH NOWAIT; END; END; diff --git a/install/24_collect_deadlock_xml.sql b/install/24_collect_deadlock_xml.sql index 6314e7f..6bf8f87 100644 --- a/install/24_collect_deadlock_xml.sql +++ b/install/24_collect_deadlock_xml.sql @@ -101,17 +101,17 @@ BEGIN END; /* - First run detection - collect last 1 hour of history if this is the first execution + First run detection - collect 3 days of history if this is the first execution */ IF NOT EXISTS (SELECT 1/0 FROM collect.deadlock_xml) AND NOT EXISTS (SELECT 1/0 FROM config.collection_log WHERE collector_name = N'deadlock_xml_collector') BEGIN - SET @minutes_back = 60; /*1 hour*/ + SET @minutes_back = 4320; /*3 days*/ SET @cutoff_time = DATEADD(MINUTE, -@minutes_back, SYSUTCDATETIME()); IF @debug = 1 BEGIN - RAISERROR(N'First run detected - collecting last 1 hour of deadlock events', 0, 1) WITH NOWAIT; + RAISERROR(N'First run detected - collecting last 3 days of deadlock events', 0, 1) WITH NOWAIT; END; END; diff --git a/install/28_collect_system_health_wrapper.sql b/install/28_collect_system_health_wrapper.sql index 2a96f3d..1c2b7fc 100644 --- a/install/28_collect_system_health_wrapper.sql +++ b/install/28_collect_system_health_wrapper.sql @@ -101,16 +101,16 @@ BEGIN END; /* - First run detection - collect last 1 hour of history if this is the first execution + First run detection - collect 3 days of history if this is the first execution */ IF NOT EXISTS (SELECT 1/0 FROM config.collection_log WHERE collector_name = N'system_health_collector') BEGIN - SET @hours_back = 1; /*1 hour*/ + SET @hours_back = 72; /*3 days*/ SET @start_date = DATEADD(HOUR, -@hours_back, SYSDATETIMEOFFSET()); IF @debug = 1 BEGIN - RAISERROR(N'First run detected - collecting last 1 hour of system health data', 0, 1) WITH NOWAIT; + RAISERROR(N'First run detected - collecting last 3 days of system health data', 0, 1) WITH NOWAIT; END; END; diff --git a/install/29_collect_default_trace.sql b/install/29_collect_default_trace.sql index 917466d..9760fab 100644 --- a/install/29_collect_default_trace.sql +++ b/install/29_collect_default_trace.sql @@ -110,17 +110,17 @@ BEGIN END; /* - First run detection - collect last 1 hour of trace data if this is the first execution + First run detection - collect all available trace data if this is the first execution Ignore CONFIG_CHANGE entries when checking for first run (those are just from enabling the trace) */ IF NOT EXISTS (SELECT 1/0 FROM collect.default_trace_events) AND NOT EXISTS (SELECT 1/0 FROM config.collection_log WHERE collector_name = N'default_trace_collector' AND collection_status = N'SUCCESS') BEGIN - SET @cutoff_time = DATEADD(HOUR, -1, SYSDATETIME()); + SET @cutoff_time = CONVERT(datetime2(7), '19000101'); IF @debug = 1 BEGIN - RAISERROR(N'First run detected - collecting last 1 hour of default trace events', 0, 1) WITH NOWAIT; + RAISERROR(N'First run detected - collecting all available default trace events', 0, 1) WITH NOWAIT; END; END; diff --git a/install/45_create_agent_jobs.sql b/install/45_create_agent_jobs.sql index c9fe080..e7ce07c 100644 --- a/install/45_create_agent_jobs.sql +++ b/install/45_create_agent_jobs.sql @@ -21,21 +21,9 @@ GO /* Create SQL Server Agent Jobs for Performance Monitor These jobs automate data collection and retention - -When @preserve_jobs = 1, existing jobs are left untouched (owner, -schedule, notifications, etc.) and only missing jobs are created. -The installer sets this to 1 when --preserve-jobs is specified. */ -DECLARE - @preserve_jobs bit = 0; - PRINT 'Creating SQL Server Agent jobs for Performance Monitor'; - -IF @preserve_jobs = 1 -BEGIN - PRINT '(preserve mode — existing jobs will not be modified)'; -END; PRINT ''; /* @@ -43,8 +31,11 @@ Job 1: PerformanceMonitor - Collection Runs scheduled master collector every 1 minute The collector checks config.collection_schedule to determine which collectors should run */ -IF @preserve_jobs = 0 -AND EXISTS + +/* +Drop existing job if it exists +*/ +IF EXISTS ( SELECT 1/0 @@ -81,55 +72,48 @@ BEGIN PRINT 'Dropped existing PerformanceMonitor - Collection job'; END; -IF NOT EXISTS -( - SELECT - 1/0 - FROM msdb.dbo.sysjobs AS j - WHERE j.name = N'PerformanceMonitor - Collection' -) -BEGIN - EXECUTE msdb.dbo.sp_add_job - @job_name = N'PerformanceMonitor - Collection', - @enabled = 1, - @description = N'Runs scheduled master collector to execute collectors based on config.collection_schedule', - @category_name = N'Data Collector'; - - EXECUTE msdb.dbo.sp_add_jobstep - @job_name = N'PerformanceMonitor - Collection', - @step_name = N'Run Scheduled Master Collector', - @subsystem = N'TSQL', - @database_name = N'PerformanceMonitor', - @command = N'EXECUTE collect.scheduled_master_collector @debug = 0;', - @retry_attempts = 0, - @on_success_action = 1; /*Quit with success*/ - - EXECUTE msdb.dbo.sp_add_jobschedule - @job_name = N'PerformanceMonitor - Collection', - @name = N'Every 1 Minute', - @freq_type = 4, /*Daily*/ - @freq_interval = 1, - @freq_subday_type = 4, /*Minutes*/ - @freq_subday_interval = 1; /*Every 1 minute*/ - - EXECUTE msdb.dbo.sp_add_jobserver - @job_name = N'PerformanceMonitor - Collection', - @server_name = N'(local)'; - - PRINT 'Created PerformanceMonitor - Collection job (runs every 1 minute)'; -END; -ELSE IF @preserve_jobs = 1 -BEGIN - PRINT 'PerformanceMonitor - Collection job already exists — preserving current settings'; -END; +/* +Create the collection job +*/ +EXECUTE msdb.dbo.sp_add_job + @job_name = N'PerformanceMonitor - Collection', + @enabled = 1, + @description = N'Runs scheduled master collector to execute collectors based on config.collection_schedule', + @category_name = N'Data Collector'; + +EXECUTE msdb.dbo.sp_add_jobstep + @job_name = N'PerformanceMonitor - Collection', + @step_name = N'Run Scheduled Master Collector', + @subsystem = N'TSQL', + @database_name = N'PerformanceMonitor', + @command = N'EXECUTE collect.scheduled_master_collector @debug = 0;', + @retry_attempts = 0, + @on_success_action = 1; /*Quit with success*/ + +EXECUTE msdb.dbo.sp_add_jobschedule + @job_name = N'PerformanceMonitor - Collection', + @name = N'Every 1 Minute', + @freq_type = 4, /*Daily*/ + @freq_interval = 1, + @freq_subday_type = 4, /*Minutes*/ + @freq_subday_interval = 1; /*Every 1 minute*/ + +EXECUTE msdb.dbo.sp_add_jobserver + @job_name = N'PerformanceMonitor - Collection', + @server_name = N'(local)'; + +PRINT 'Created PerformanceMonitor - Collection job (runs every 1 minute)'; PRINT ''; /* Job 2: PerformanceMonitor - Data Retention Purges old performance monitoring data daily at 2am */ -IF @preserve_jobs = 0 -AND EXISTS + +/* +Drop existing job if it exists +*/ +IF EXISTS ( SELECT 1/0 @@ -166,54 +150,47 @@ BEGIN PRINT 'Dropped existing PerformanceMonitor - Data Retention job'; END; -IF NOT EXISTS -( - SELECT - 1/0 - FROM msdb.dbo.sysjobs AS j - WHERE j.name = N'PerformanceMonitor - Data Retention' -) -BEGIN - EXECUTE msdb.dbo.sp_add_job - @job_name = N'PerformanceMonitor - Data Retention', - @enabled = 1, - @description = N'Purges old performance monitoring data', - @category_name = N'Data Collector'; - - EXECUTE msdb.dbo.sp_add_jobstep - @job_name = N'PerformanceMonitor - Data Retention', - @step_name = N'Run Data Retention', - @subsystem = N'TSQL', - @database_name = N'PerformanceMonitor', - @command = N'EXECUTE config.data_retention @debug = 1;', - @retry_attempts = 0, - @on_success_action = 1; /*Quit with success*/ - - EXECUTE msdb.dbo.sp_add_jobschedule - @job_name = N'PerformanceMonitor - Data Retention', - @name = N'Daily at 2am', - @freq_type = 4, /*Daily*/ - @freq_interval = 1, - @active_start_time = 20000; /*2:00 AM*/ - - EXECUTE msdb.dbo.sp_add_jobserver - @job_name = N'PerformanceMonitor - Data Retention', - @server_name = N'(local)'; - - PRINT 'Created PerformanceMonitor - Data Retention job (runs daily at 2:00 AM)'; -END; -ELSE IF @preserve_jobs = 1 -BEGIN - PRINT 'PerformanceMonitor - Data Retention job already exists — preserving current settings'; -END; +/* +Create the data retention job +*/ +EXECUTE msdb.dbo.sp_add_job + @job_name = N'PerformanceMonitor - Data Retention', + @enabled = 1, + @description = N'Purges old performance monitoring data', + @category_name = N'Data Collector'; + +EXECUTE msdb.dbo.sp_add_jobstep + @job_name = N'PerformanceMonitor - Data Retention', + @step_name = N'Run Data Retention', + @subsystem = N'TSQL', + @database_name = N'PerformanceMonitor', + @command = N'EXECUTE config.data_retention @debug = 1;', + @retry_attempts = 0, + @on_success_action = 1; /*Quit with success*/ + +EXECUTE msdb.dbo.sp_add_jobschedule + @job_name = N'PerformanceMonitor - Data Retention', + @name = N'Daily at 2am', + @freq_type = 4, /*Daily*/ + @freq_interval = 1, + @active_start_time = 20000; /*2:00 AM*/ + +EXECUTE msdb.dbo.sp_add_jobserver + @job_name = N'PerformanceMonitor - Data Retention', + @server_name = N'(local)'; + +PRINT 'Created PerformanceMonitor - Data Retention job (runs daily at 2:00 AM)'; PRINT ''; /* Job 3: PerformanceMonitor - Hung Job Monitor Monitors the collection job for hung state every 5 minutes */ -IF @preserve_jobs = 0 -AND EXISTS + +/* +Drop existing job if it exists +*/ +IF EXISTS ( SELECT 1/0 @@ -250,52 +227,42 @@ BEGIN PRINT 'Dropped existing PerformanceMonitor - Hung Job Monitor job'; END; -IF NOT EXISTS -( - SELECT - 1/0 - FROM msdb.dbo.sysjobs AS j - WHERE j.name = N'PerformanceMonitor - Hung Job Monitor' -) -BEGIN - EXECUTE msdb.dbo.sp_add_job - @job_name = N'PerformanceMonitor - Hung Job Monitor', - @enabled = 1, - @description = N'Monitors collection job for hung state and stops it if needed', - @category_name = N'Data Collector'; - - EXECUTE msdb.dbo.sp_add_jobstep - @job_name = N'PerformanceMonitor - Hung Job Monitor', - @step_name = N'Check for Hung Collection Job', - @subsystem = N'TSQL', - @database_name = N'PerformanceMonitor', - @command = N'EXECUTE config.check_hung_collector_job +/* +Create the hung job monitor job +*/ +EXECUTE msdb.dbo.sp_add_job + @job_name = N'PerformanceMonitor - Hung Job Monitor', + @enabled = 1, + @description = N'Monitors collection job for hung state and stops it if needed', + @category_name = N'Data Collector'; + +EXECUTE msdb.dbo.sp_add_jobstep + @job_name = N'PerformanceMonitor - Hung Job Monitor', + @step_name = N'Check for Hung Collection Job', + @subsystem = N'TSQL', + @database_name = N'PerformanceMonitor', + @command = N'EXECUTE config.check_hung_collector_job @job_name = N''PerformanceMonitor - Collection'', @normal_max_duration_minutes = 5, @first_run_max_duration_minutes = 30, @stop_hung_job = 1, @debug = 0;', - @retry_attempts = 0, - @on_success_action = 1; /*Quit with success*/ - - EXECUTE msdb.dbo.sp_add_jobschedule - @job_name = N'PerformanceMonitor - Hung Job Monitor', - @name = N'Every 5 Minutes', - @freq_type = 4, /*Daily*/ - @freq_interval = 1, - @freq_subday_type = 4, /*Minutes*/ - @freq_subday_interval = 5; /*Every 5 minutes*/ - - EXECUTE msdb.dbo.sp_add_jobserver - @job_name = N'PerformanceMonitor - Hung Job Monitor', - @server_name = N'(local)'; - - PRINT 'Created PerformanceMonitor - Hung Job Monitor job (runs every 5 minutes)'; -END; -ELSE IF @preserve_jobs = 1 -BEGIN - PRINT 'PerformanceMonitor - Hung Job Monitor job already exists — preserving current settings'; -END; + @retry_attempts = 0, + @on_success_action = 1; /*Quit with success*/ + +EXECUTE msdb.dbo.sp_add_jobschedule + @job_name = N'PerformanceMonitor - Hung Job Monitor', + @name = N'Every 5 Minutes', + @freq_type = 4, /*Daily*/ + @freq_interval = 1, + @freq_subday_type = 4, /*Minutes*/ + @freq_subday_interval = 5; /*Every 5 minutes*/ + +EXECUTE msdb.dbo.sp_add_jobserver + @job_name = N'PerformanceMonitor - Hung Job Monitor', + @server_name = N'(local)'; + +PRINT 'Created PerformanceMonitor - Hung Job Monitor job (runs every 5 minutes)'; PRINT ''; /*