503 lines
16 KiB
Transact-SQL
503 lines
16 KiB
Transact-SQL
/*=============================================================================
|
|
|
|
User guide
|
|
---------------------------------------------------
|
|
|
|
01. Create Table [Replication_queue_history]
|
|
02. Create Indexes [NCIX_?]
|
|
03. Create stored procedure [Get_replication_counters]
|
|
04. Create Job [DR92280 - Monitoring SQL Server Replication]
|
|
|
|
Usage context
|
|
------------------------------------------
|
|
To collect performance status for all publication's subscriptions in the server
|
|
|
|
|
|
Parameters
|
|
------------------------------------------
|
|
|
|
Creation : 27.10.21 / RTC
|
|
|
|
Modification : 17.03.2022 - FLA : Change DBA mail
|
|
22.04.2022 - FLA : Correct SP location in job
|
|
|
|
=============================================================================*/
|
|
|
|
|
|
/***************************************************************/
|
|
/****** Create Table [Replication_queue_history] *******/
|
|
/***************************************************************/
|
|
USE [HCITools]
|
|
GO
|
|
|
|
SET ANSI_NULLS ON
|
|
GO
|
|
|
|
SET QUOTED_IDENTIFIER ON
|
|
GO
|
|
|
|
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[mon].[Replication_queue_history]') AND type in (N'U'))
|
|
BEGIN
|
|
|
|
CREATE TABLE mon.Replication_queue_history(
|
|
Replication_queue_history_Id INT IDENTITY(1,1) NOT NULL,
|
|
RQH_subscriber_db VARCHAR(50) NOT NULL,
|
|
RQH_records_in_queue NUMERIC(18, 0) NULL,
|
|
RQH_catch_up_time NUMERIC(18, 0) NULL,
|
|
RQH_log_date DATETIME NOT NULL
|
|
CONSTRAINT PK_EPR_Replication_queue_history PRIMARY KEY CLUSTERED
|
|
(
|
|
RQH_subscriber_db ASC, RQH_log_date DESC
|
|
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
|
|
) ON [PRIMARY]
|
|
END
|
|
GO
|
|
|
|
/***************************************************************/
|
|
/****** Create Procedure [Get_replication_counters] *******/
|
|
/***************************************************************/
|
|
|
|
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mon_Get_Replication_Counters]') AND type in (N'P', N'PC'))
|
|
DROP PROCEDURE [dbo].[mon_Get_Replication_Counters]
|
|
GO
|
|
|
|
CREATE PROCEDURE [dbo].[mon_Get_Replication_Counters]
|
|
@in_debug INT = NULL
|
|
AS
|
|
|
|
/*=============================================================================
|
|
|
|
Explication du traitement realise par la SP
|
|
-------------------------------------------
|
|
To collect performance counters in SQL Server Replication
|
|
|
|
Contexte d'utilisation
|
|
----------------------
|
|
Job : DR92280 - Monitoring SQL Server Replication
|
|
|
|
Parametres
|
|
----------
|
|
@in_debug
|
|
|
|
Creation : 27.10.2021 / RTC
|
|
|
|
Modifications :
|
|
|
|
=============================================================================*/
|
|
|
|
DECLARE @cmd NVARCHAR(max)
|
|
DECLARE @publisher SYSNAME,
|
|
@publisher_db SYSNAME,
|
|
@publication SYSNAME,
|
|
@pubtype INT
|
|
DECLARE @subscriber SYSNAME,
|
|
@subscriber_db SYSNAME,
|
|
@subtype INT
|
|
DECLARE @cmdcount INT,
|
|
@processtime INT
|
|
DECLARE @ParmDefinition NVARCHAR(500)
|
|
DECLARE @JobName SYSNAME
|
|
DECLARE @minutes INT,
|
|
@threshold INT,
|
|
@maxCommands INT,
|
|
@mail CHAR(1) = 'N'
|
|
SET @minutes = 60 --> Define how many minutes latency before you would like to be notified
|
|
SET @maxCommands = 80000 ---> change this to represent the max number of outstanding commands to be proceduresed before notification
|
|
SET @threshold = @minutes * 60
|
|
|
|
/* Drop all temp tables */
|
|
IF OBJECT_ID(N'tempdb..#PublisherInfo') is not null
|
|
drop table #PublisherInfo
|
|
|
|
if exists (SELECT *
|
|
FROM [TempDB].sys.objects o WITH (NOLOCK)
|
|
WHERE o.name = '##PublicationInfo'
|
|
AND o.type IN (N'U'))
|
|
Drop table ##PublicationInfo
|
|
|
|
|
|
if exists (SELECT *
|
|
FROM [TempDB].sys.objects o WITH (NOLOCK)
|
|
WHERE o.name = '##SubscriptionInfo'
|
|
AND o.type IN (N'U'))
|
|
Drop table ##SubscriptionInfo
|
|
|
|
SELECT *
|
|
INTO #PublisherInfo
|
|
FROM
|
|
OPENROWSET('SQLOLEDB',
|
|
'SERVER=(LOCAL);TRUSTED_CONNECTION=YES;',
|
|
'SET FMTONLY OFF EXEC distribution.dbo.sp_replmonitorhelppublisher WITH RESULT SETS ((publisher sysname, Distribution_db sysname, status int, warning int, publication_count int, returnstamp bigint))') --
|
|
|
|
select *
|
|
from #PublisherInfo
|
|
|
|
SELECT @publisher = publisher
|
|
FROM #PublisherInfo
|
|
|
|
SET @cmd
|
|
= 'SELECT * INTO ##PublicationInfo FROM OPENROWSET(''SQLOLEDB'',''SERVER=(LOCAL);TRUSTED_CONNECTION=YES''
|
|
,''SET FMTONLY OFF EXEC distribution.dbo.sp_replmonitorhelppublication @publisher= ''''' + @publisher
|
|
+ ''''' with result sets ((publisher_db sysname, publication sysname, publication_id int, publication_type int, status int, warning int, worst_latency int, best_latency int, average_latency int, last_distsync datetime,
|
|
retention int, latencythreshold int, expirationthreshold int, agentnotrunningthreshold int, subscriptioncount int, runningdistagentcount int, snapshot_agentname sysname, logreader_agentname sysname,
|
|
qreader_agentname sysname, worst_runspeedPerf int, best_runspeedPerf int, average_runspeedPerf int, retention_period_unit int, publisher sysname))'')'
|
|
|
|
--select @cmd
|
|
|
|
EXEC sp_executesql @cmd
|
|
|
|
select *
|
|
FROM ##PublicationInfo
|
|
|
|
|
|
SELECT @publisher_db = publisher_db,
|
|
@publication = publication,
|
|
@pubtype = publication_type
|
|
FROM ##PublicationInfo
|
|
|
|
SET @cmd
|
|
= 'SELECT * INTO ##SubscriptionInfo FROM OPENROWSET(''SQLOLEDB'',''SERVER=(LOCAL);TRUSTED_CONNECTION=YES''
|
|
,''SET FMTONLY OFF EXEC distribution.dbo.sp_replmonitorhelpsubscription @publisher=''''' + @publisher
|
|
+ ''''',@publication_type=' + CONVERT(CHAR(1), @pubtype)
|
|
+ ' with result sets ((status int, warning int, subscriber sysname, subscriber_db sysname, publisher_db sysname,
|
|
publication sysname, publication_type int, subtype int, latency int, latencythreshold int, agentnotrunning int, agentnotrunningthreshold int, timetoexpiration int, expirationthreshold int,
|
|
last_distsync datetime, distribution_agentname sysname, mergeagentname sysname, mergesubscriptionfriendlyname sysname, mergeagentlocation sysname, mergeconnectiontype int, mergePerformance int,
|
|
mergerunspeed float, mergerunduration int, monitorranking int, distributionagentjobid binary(16), mergeagentjobid binary(16), distributionagentid int, distributionagentprofileid int,
|
|
mergeagentid int, mergeagentprofileid int, logreaderagentname sysname, publisher sysname ))'')'
|
|
|
|
--select @cmd
|
|
|
|
EXEC sp_executesql @cmd
|
|
|
|
select *
|
|
from ##SubscriptionInfo
|
|
|
|
|
|
ALTER TABLE ##SubscriptionInfo
|
|
ADD PendingCmdCount INT NULL,
|
|
EstimatedProcessTime INT NULL
|
|
|
|
DECLARE cur_sub CURSOR READ_ONLY FOR
|
|
SELECT @publisher,
|
|
s.publisher_db,
|
|
s.publication,
|
|
s.subscriber,
|
|
s.subscriber_db,
|
|
s.subtype,
|
|
s.distribution_agentname
|
|
FROM ##SubscriptionInfo s
|
|
|
|
OPEN cur_sub
|
|
FETCH NEXT FROM cur_sub
|
|
INTO @publisher,
|
|
@publisher_db,
|
|
@publication,
|
|
@subscriber,
|
|
@subscriber_db,
|
|
@subtype,
|
|
@JobName
|
|
|
|
WHILE @@FETCH_STATUS = 0
|
|
BEGIN
|
|
SET @cmd
|
|
= 'SELECT @cmdcount=pendingcmdcount, @processtime=estimatedprocesstime FROM OPENROWSET(''SQLOLEDB'',''SERVER=(LOCAL);TRUSTED_CONNECTION=YES''
|
|
,''SET FMTONLY OFF EXEC distribution.dbo.sp_replmonitorsubscriptionpendingcmds @publisher='''''
|
|
+ @publisher + ''''',@publisher_db=''''' + @publisher_db + ''''',@publication=''''' + @publication
|
|
+ ''''',@subscriber=''''' + @subscriber + ''''',@subscriber_db=''''' + @subscriber_db
|
|
+ ''''',@subscription_type=' + CONVERT(CHAR(1), @subtype)
|
|
+ ' With result sets ((pendingcmdcount int, estimatedprocesstime int))'')'
|
|
SET @ParmDefinition = N'@cmdcount INT OUTPUT,
|
|
@processtime INT OUTPUT'
|
|
select @cmd
|
|
EXEC sp_executesql @cmd,
|
|
@ParmDefinition,
|
|
@cmdcount OUTPUT,
|
|
@processtime OUTPUT
|
|
|
|
SELECT @cmdcount,
|
|
@processtime
|
|
|
|
UPDATE ##SubscriptionInfo
|
|
SET PendingCmdCount = @cmdcount,
|
|
EstimatedProcessTime = @processtime
|
|
WHERE subscriber_db = @subscriber_db
|
|
|
|
INSERT INTO HCITools.mon.Replication_queue_history
|
|
VALUES (@subscriber, @cmdcount, @processtime, GETDATE())
|
|
|
|
FETCH NEXT FROM cur_sub
|
|
INTO @publisher,
|
|
@publisher_db,
|
|
@publication,
|
|
@subscriber,
|
|
@subscriber_db,
|
|
@subtype,
|
|
@JobName
|
|
END
|
|
|
|
CLOSE cur_sub
|
|
DEALLOCATE cur_sub
|
|
|
|
GO
|
|
|
|
/***************************************************************/
|
|
/****** Create Procedure [Purge_repl_queue_hist] *******/
|
|
/***************************************************************/
|
|
|
|
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mon_purge_repl_queue_hist]') AND type in (N'P', N'PC'))
|
|
DROP PROCEDURE [dbo].[mon_Purge_repl_queue_hist]
|
|
GO
|
|
|
|
CREATE PROCEDURE [dbo].[mon_Purge_repl_queue_hist]
|
|
@in_debug INT = NULL
|
|
AS
|
|
|
|
/*=============================================================================
|
|
|
|
Explication du traitement realise par la SP
|
|
-------------------------------------------
|
|
To purge performance counters history in HCITools
|
|
|
|
Contexte d'utilisation
|
|
----------------------
|
|
Job : DR92280 - Monitoring SQL Server Replication
|
|
|
|
Parametres
|
|
----------
|
|
@in_debug
|
|
|
|
Creation : 27.10.2021 / RTC
|
|
|
|
Modifications :
|
|
|
|
=============================================================================*/
|
|
DECLARE @delDate datetime = getdate()-30
|
|
DELETE FROM mon.Replication_queue_history
|
|
WHERE RQH_log_date < @deldate
|
|
|
|
GO
|
|
|
|
/***************************************************************/
|
|
/** Create Job [DR92280 - Monitoring SQL Server Replication] **/
|
|
/***************************************************************/
|
|
|
|
|
|
/* Drop existing standard schedule for job */
|
|
declare @schedule_id int
|
|
declare c_schedules cursor local forward_only static 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'DR92280 - Monitoring SQL Server Replication'
|
|
|
|
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'DR92280 - Monitoring SQL Server Replication')
|
|
EXEC msdb.dbo.sp_delete_job @job_name = N'DR92280 - Monitoring SQL Server Replication', @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'DR92280 - Monitoring SQL Server Replication',
|
|
@enabled=1,
|
|
@notify_level_eventlog=0,
|
|
@notify_level_email=0,
|
|
@notify_level_netsend=0,
|
|
@notify_level_page=0,
|
|
@delete_level=0,
|
|
@description=N'27.10.2021 /RTC : Collect Data for replication monitoring',
|
|
@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'Repl monitor collect data',
|
|
@step_id=2,
|
|
@cmdexec_success_code=0,
|
|
@on_success_action=3,
|
|
@on_success_step_id=0,
|
|
@on_fail_action=4,
|
|
@on_fail_step_id=5,
|
|
@retry_attempts=0,
|
|
@retry_interval=0,
|
|
@os_run_priority=0, @subsystem=N'TSQL',
|
|
@command=N'exec [dbo].[mon_Get_Replication_Counters]',
|
|
@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'Purge queue history',
|
|
@step_id=3,
|
|
@cmdexec_success_code=0,
|
|
@on_success_action=3,
|
|
@on_success_step_id=0,
|
|
@on_fail_action=4,
|
|
@on_fail_step_id=5,
|
|
@retry_attempts=0,
|
|
@retry_interval=0,
|
|
@os_run_priority=0, @subsystem=N'TSQL',
|
|
@command=N'exec [dbo].[mon_Purge_repl_queue_hist]',
|
|
@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=4,
|
|
@cmdexec_success_code=0,
|
|
@on_success_action=1,
|
|
@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 for success */',
|
|
@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'Send mail KO',
|
|
@step_id=5,
|
|
@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 Get_Job_Error_Info @in_JobName = ''DR92280 - Monitoring SQL Server Replication'', @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'DR92280-DR',
|
|
@enabled=1,
|
|
@freq_type=4,
|
|
@freq_interval=1,
|
|
@freq_subday_type=4,
|
|
@freq_subday_interval=10,
|
|
@freq_relative_interval=0,
|
|
@freq_recurrence_factor=0,
|
|
@active_start_date=20210820,
|
|
@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 'DR92280%'
|
|
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
|