By: Nisarg Upadhyay | Updated: 2018-11-20 | Comments (1) | Related: > Replication
Problem
How can I send an automated email notification when SQL Server data replication latency between a publisher and subscriber is higher than 60 seconds?
Solution
To monitor SQL Server replication, we can use a Tracer Token. The Tracer Token measures the latency between the Publisher and Distributor and the Distributor to Subscribers. This tip explains briefly about tracer tokens, how they work and how to configure them.
In this tip, I am going show how to send an email notification when latency between the Publisher and Distributor or the Publisher and Subscriber is higher than 60 seconds.
To set this up, we must create a SQL Server Agent Job that executes every fifteen minutes. The SQL Server Agent Job executes a stored procedure which performs the following tasks:
- Creates a new tracer token in the publication database using system stored procedure named "sp_posttracertoken".
- Populates tracer token IDs using system stored procedure named "sp_helptracertokens" and stores it in #TracerToken table.
- Populates a recent tracer token ID from the #TracerToken table and store it in "@LiTokenID" variable.
- Passes the tracer token ID, stored in "@LiTokenID" to the sp_helptracertokens procedure and saves the output in #Latency table.
- Check the value of latency in "OVERALL_LATENCY" column of #Latency table. If it is higher than 1 minute than it sends an email notification.
Replication Configuration
First, let's review the replication configuration. To do that execute the following query on the publisher database.
SELECT DistributionAgent.subscriber_db [Subscriber DB], DistributionAgent.publication [PUB Name], RIGHT(LEFT(DistributionAgent.NAME, Len(DistributionAgent.NAME) - (Len(DistributionAgent.id) + 1 )), Len(LEFT(DistributionAgent.NAME, Len(DistributionAgent.NAME) - (Len(DistributionAgent.id) + 1 ))) - ( 10 + Len(DistributionAgent.publisher_db) + ( CASE WHEN DistributionAgent.publisher_db = 'ALL' THEN 1 ELSE Len(DistributionAgent.publication) + 2 END ) )) [SUBSCRIBER], (CASE WHEN DistributionAgent.subscription_type = '0' THEN 'Push' WHEN DistributionAgent.subscription_type = '1' THEN 'Pull' WHEN DistributionAgent.subscription_type = '2' THEN 'Anonymous' ELSE Cast(DistributionAgent.subscription_type AS VARCHAR) END ) [Subscrition Type], DistributionAgent.publisher_db + ' - ' + Cast(DistributionAgent.publisher_database_id AS VARCHAR) [Publisher Database], DistributionAgent.NAME [Publisher - PublisherDB - Publication - SubscriptionName - AgentID] FROM distribution.dbo.msdistribution_agents DistributionAgent WHERE DistributionAgent.subscriber_db <> 'virtual'
This screen shot below is the output of the above query.
Replication Latency Check - Code Explanation
The following explains the code used to check for replication latency issues. Further down in the article is a complete code listing you can use. Also, this example uses the AdventureWorks2014 database. You will need to update the code you use to reflect the database name you are using for replication.
The following code populates the publication name and stores it in the "@lsPublication" variable. This code block must be executed in the publication database.
DECLARE @lsPublication AS sysname; SET @lsPublication = (SELECT name FROM AdventureWorks2014..syspublications WHERE name = 'Customer_Publication')
This code creates a tracer token in the publication database.
EXEC AdventureWorks2014.sys.sp_posttracertoken @Publication = @lsPublication, @tracer_token_id = @liTokenID OUTPUT;
This INSERT command stores the information of recently created tracer tokens in the temp table.
INSERT #tracer_tokens (tracer_id, publisher_commit) EXEC AdventureWorks2014.sys.sp_helptracertokens @Publication = @lsPublication;
The following code block stores the recent tracer token ID of in "@LiTokenID" variable.
SET @liTokenID = ( SELECT TOP 1 tracer_id FROM #tracer_tokens ORDER BY publisher_commit DESC ) DROP TABLE #tracer_tokens
Below is code that creates a temp table to store the latency results of a tracer token.
CREATE TABLE #Latency ( DISTRIBUTOR_LATENCY INT, SUBSCRIBER VARCHAR(255), SUBSCRIBER_DB VARCHAR(255), SUBSCRIBER_LATENCY INT, OVERALL_LATENCY INT )
Once the table gets created, the following code block populates the latency values of token ID, stored in the "@LiTokenID" variable using the "sp_helptracertokenhistory" stored procedure and inserts it into the #Latency table.
INSERT INTO #Latency (distributor_latency, subscriber, subscriber_db, subscriber_latency, overall_latency) EXEC AdventureWorks2014.sys.sp_helptracertokenhistory @Publication = @lsPublication, @tracer_id = @liTokenID;
The following code block populates the default SQL Server Database Mail profile and stores it in the "@ProfileName" variable.
DECLARE @DBMailProfile TABLE (ProfileID INT, ProfileName SYSNAME, [Description] NVARCHAR(4000)) DECLARE @ProfileName SYSNAME INSERT INTO @DBMailProfile (ProfileID, ProfileName, [Description]) EXEC msdb.dbo.sysmail_help_profile_sp @profile_id = 1 SET @ProfileName = (SELECT ProfileName FROM @DBMailProfile)
The following code block checks the value of the "overall_latency" column of the #Latency table. If the value is higher than 1 minute then an email is sent.
IF (SELECT MAX(ISNULL(OVERALL_LATENCY, 100)) FROM #Latency) >= 59 BEGIN SET @lsMessage = '<p style="font-family:Arial; font-size:10pt">There is an error in database replication. ' + 'Latency has exceeded 1 minute. This can be caused by a patch, configuration or database error. ' + 'Please Login to publisher server, then use the following command to open <b>SQL Replication Monitor</b> to determine the error.' + '<br><br>' + '<table border=1 cellspacing=0 cellpadding=0 bgcolor=#F2F2F2><tr><td><font face="Courier New" size=2>"C:\"Program Files (x86)"\"Microsoft SQL Server"\120\Tools\Binn\SqlMonitor.exe" </font></td></tr></table>' + '<br>' + '<b>NOTE:</b> This alert will be generated every 15 minutes until replication is caught up for the AdventureWorks2014 databases on <b>all</b> subscribers. ' + '</p>' EXEC msdb.dbo.sp_send_dbmail @recipients='[email protected]', @body=@lsMessage, @subject='Replication Alert: Higher Latency', @file_attachments='', @copy_recipients='', @blind_copy_recipients='', @importance='high', @body_format='HTML', @profile_name=@ProfileName END
Create Replication Latency Check Stored Procedure
The following is the complete set of code for the stored procedure.
CREATE PROCEDURE [dbo].[sp_ReplicationLatencyMonitor] AS Begin SET NOCOUNT ON DECLARE @liTokenID AS int; DECLARE @lsMessage VARCHAR(2000) DECLARE @lsPublication AS sysname; SET @lsPublication = (SELECT name FROM AdventureWorks2014..syspublications WHERE name = 'Customer_Publication') DECLARE @DBMailProfile TABLE (ProfileID INT, ProfileName SYSNAME, [Description] NVARCHAR(4000)) DECLARE @ProfileName SYSNAME INSERT INTO @DBMailProfile (ProfileID, ProfileName, [Description]) EXEC msdb.dbo.sysmail_help_profile_sp @profile_id = 1 SET @ProfileName = (SELECT ProfileName FROM @DBMailProfile) EXEC AdventureWorks2014.sys.sp_posttracertoken @Publication = @lsPublication, @tracer_token_id = @liTokenID OUTPUT; CREATE TABLE #tracer_tokens (tracer_id int, publisher_commit datetime) INSERT #tracer_tokens (tracer_id, publisher_commit) EXEC AdventureWorks2014.sys.sp_helptracertokens @Publication = @lsPublication; SET @liTokenID = ( SELECT TOP 1 tracer_id FROM #tracer_tokens ORDER BY publisher_commit DESC ) DROP TABLE #tracer_tokens CREATE TABLE #Latency ( DISTRIBUTOR_LATENCY INT, SUBSCRIBER VARCHAR(255), SUBSCRIBER_DB VARCHAR(255), SUBSCRIBER_LATENCY INT, OVERALL_LATENCY INT ) INSERT INTO #Latency (distributor_latency, subscriber, subscriber_db, subscriber_latency, overall_latency) EXEC AdventureWorks2014.sys.sp_helptracertokenhistory @Publication = @lsPublication, @tracer_id = @liTokenID; IF (SELECT MAX(ISNULL(OVERALL_LATENCY, 100)) FROM #Latency) >= 59 BEGIN SET @lsMessage = '<p style="font-family:Arial; font-size:10pt">There is an error in database replication. ' + 'Latency has exceeded 1 minute. This can be caused by a patch, configuration or database error. ' + 'Please Login to publisher server, then use the following command to open <b>SQL Replication Monitor</b> to determine the error.' + '<br><br>' + '<table border=1 cellspacing=0 cellpadding=0 bgcolor=#F2F2F2><tr><td><font face="Courier New" size=2>"C:\"Program Files (x86)"\"Microsoft SQL Server"\120\Tools\Binn\SqlMonitor.exe" </font></td></tr></table>' + '<br>' + '<b>NOTE:</b> This alert will be generated every 15 minutes until replication is caught up for the AdventureWorks2014 databases on <b>all</b> subscribers. ' + '</p>' EXEC msdb.dbo.sp_send_dbmail @recipients='[email protected]', @body=@lsMessage, @subject='Replication Alert: Higher Latency', @file_attachments='', @copy_recipients='', @blind_copy_recipients='', @importance='high', @body_format='HTML', @profile_name=@ProfileName END DROP TABLE #Latency; SET NOCOUNT OFF End
Create Replication Latency Check SQL Agent Job
Once the procedure is created, create a SQL Server Agent Job to execute every 15 minutes. To do that, open SQL Server Management Studio on the publisher database server. Expand the SQL instance, Expand SQL Server Agent and right click on Jobs and select "New Job." See the following image:
The dialog box "New Job" opens. Provide the desired Job name and select "Steps" option in "Select a page" menu and click on "New" to add a job step. See the following image:
A dialog box "New Job Step" opens. In the Step Name text box, provide desired step name. In type drop-down box, select "Transact-SQL Script (T-SQL)." Copy and paste the following T-SQL code in the "Command" drop-down box.
Use AdventureWorks2014 GO Exec [sp_ReplicationLatencyMonitor]
Click OK to close the dialog box. See the following image:
On the "New job" screen, select "Schedules" option and click the "New" button to add a job execution schedule. See the following image:
A dialog box "New Job Schedule" opens to configure the Job schedule. In Name text box, provide an appropriate name, in frequency, select "Daily" in the occurs drop down box, and in daily frequency, select 15 minutes and click ok. See the following image:
Once the schedule and job steps configuration complete, click OK to close the job.
Sample Replication Latency Email
When the code finds replication latency issues it sends the following email.
Next Steps
- Check out the following resources:
About the author
This author pledges the content of this article is based on professional experience and not AI generated.
View all my tips
Article Last Updated: 2018-11-20