Monitoring SQL Server Transactional replication

Source: Internet
Author: User
Tags getdate

Monitoring SQL Server Transactional replication

In general, we can use the Replication Monitor in SSMs to monitor replication. But we can't stare at it for 24 hours, and we have to use an automated way to monitor it. Microsoft provides system stored procedure DBO.SP_REPLMONITORSUBSCRIPTIONPENDINGCMDS in the distribution database to return the number of commands waiting on a subscription, as well as the estimated time required to post all these commands to subscribers. I created a job that runs every 10 minutes, saves the state's history data to a table, and retains the data for 14 days.

This table is created in the DBA database of the Subscriber server with the following code:

CREATE TABLE dbo. Replication_qu_history (
subscriber_db varchar () NOT NULL,
Records_in_que numeric (0) NULL,
Catchuptime numeric (0) NULL,
logdate datetime not NULL,
CONSTRAINT pk_epr_replication_que_history PRIMARY KEY CLUSTERED
(
subscriber_db ASC, logdate DESC
) on PRIMARY
GO

Table data is generated through monitoring stored procedures and can be used to find problems with historical data. However, it is more necessary to monitor what is happening now.

There are three things that can help determine the health of a replication.

1. Copy the status of the related job.

2. Delay, especially the distribution delay measured by the counter dist:delivery latency.

3. Number of non-executed commands waiting for subscription.

I focused my attention on the distribution delay, because from past experience, the problem of distribution delay was more pronounced than the log read delay. Most of the time, the distribution delay is due to an increase in transaction volume. For example, an index rebuild on a large table that publishes data causes a sudden increase in transaction log volume, resulting in more data than is expected to be replicated.

If you have a large number of commands waiting to be distributed, it is sometimes possible that the Distribution Agent job is not running. On the other hand, sometimes this job is running, but not keeping up. By restarting the agent, the job starts processing the commands that are not executed.

Before we start, we need to know the information about replication, such as the name of the Publisher and Subscribers, the name of the Distribution Agent job, and so on. Microsoft provides a number of stored procedures in the distribution database to collect this information. The author's distribution database is together with the Subscriber database, so the script is simpler than the different servers.

1. First, perform sp_replmonitorhelppublisher in the distribution database to obtain monitoring information for all publishers.

2. Then, perform sp_replmonitorhelppublication on the distribution database to return monitoring information for all publications.

3. Finally, execution sp_replmonitorhelpsubscription returns monitoring information for all subscriptions.

This information contains some time-lapse indicator data, so after executing this stored procedure, I have some key information.

The following is the code used to gather information:

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 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 select * into  #PublisherInfo from openrowset (' SQLOLEDB ',  ' server= (LOCAL); Trusted_connection=yes; ',  ' set fmtonly off exec distribution.dbo.sp_ Replmonitorhelppublisher ') 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  +  ') '--select  @cmd exec sp_ executesql  @cmd 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)  +  '--select  @cmd exec sp_executesql  @cmd alter table ## Subscriptioninfo Add pendingcmdcount int null, Estimatedprocesstime int null

After you know the basic information about the Publisher and the Subscriber, then check the status of the distribution job. They should be running all the time. If it is not running, you have to start it. If I need to restart a job, I will set the identity to force send message alert.

I'm not trying to send an email alert just to check the status of all subscriptions. If the set of data exceeds the set threshold, the message alarm will be triggered. I use a cursor to iterate through all the subscriptions, which is the easiest way to gather information. I use this information as a parameter to other stored procedures to determine whether the Distribution Agent is running and to restart the agent.

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 = '  +&nbSP; @subscriber_db +  ', @subscription_type = '  + convert (CHAR (1), @subtype)  +  '; '  +  ' set  @ParmDefinition  = n ' @cmdcount  int output, @processtime  int  output '--select  @cmd exec sp_executesql  @cmd, @ParmDefinition, @cmdcount  output, @ Processtime output update # #SubscriptionInfo set pendingcmdcount =  @cmdcount,  estimatedprocesstime =  @processtime where subscriber_db =  @subscriber_db insert  Into dba.dbo.replication_que_history VALUES (@subscriber_db,  @cmdcount,  @processtime,  GETDATE ())-- find out if the distribution job with the high  Number of outstanding commands running or not-- if it is  Running then sometimes stopping and starting the agent fixes the  issue If exisTS (select * from tempdb. Information_schema. tables where table_name like  ' # #JobInfo% ') drop table # #JobInfo set  @cmd  =  ' select * into # #JobInfo  from openrowset (' SQLOLEDB ', ' server= (LOCAL); Trusted_connection=yes ', ' set fmtonly off exec msdb.dbo.sp_help_job  @job_name = ' ' +   @JobName  +  "", @job_aspect = ' job ' ") ' exec sp_executesql  @cmd if  @cmdcount  >  @maxCommands  OR  (@processtime  >  @threshold  AND  @cmdcount  > 0) BEGIN if  (select current_execution_status from # #JobInfo)  = 1
 -- this means job is currently executing so stop/start it BEGIN exec distribution.dbo.sp_msstopdistribution_agent @publisher  =  @publisher,  @publisher_ db =  @publisher_db,  @publication  =  @pubLication,  @subscriber  =  @subscriber,  @subscriber_db  =  @subscriber_db WAITFOR  DELAY  ' 00:00:05 '  ---- 5 second delay set  @mail  =  ' Y ' End end-- select name, current_execution_status from # #JobInfo if  (select current_execution _status from # #JobInfo)  <> 1 -- if the job is not  running start it BEGIN exec distribution.dbo.sp_msstartdistribution_agent @publisher  =   @publisher,  @publisher_db  =  @publisher_db,  @publication  =  @publication,   @subscriber  =  @subscriber,  @subscriber_db  =  @subscriber_db set  @mail  =   ' Y '  -- send email if job has stopped and needed to  be restarted END drop table # #JobInfo fetch next from cur_sub into  @publisher, &NBSP; @publisher_db,  @publication,  @subscriber,  @subscriber_db,  @subtype,  @JobName END Close cur_sub deallocate cur_sub

Run Sp_replmonitorsubscriptionpendingcmds to collect the command that was not executed and the expected time to keep up.

This is the information I want to store in the history table, so I can see how replication is performing.

We need to determine an acceptable latency threshold. I use it here for 6 minutes, meaning that if the replicated database is less than 6 minutes behind the publication database, it will be alerted. Also determine the maximum number of non-distributed commands. If this amount fluctuates upward, there may be a problem. You can choose to take action when the number is set to high. I chose to have 80,000 non-distributed commands for this system.

I acquired this data after having the Copy queue check job run for two weeks. Make sure that these jobs run like index rebuild jobs. I looked at the maximum number of non-distributed commands and the maximum latency for some time and determined that my settings would be larger. I don't want to be woken up at night because of a temporary system backup caused by the index rebuild job, which is automatically restored.

The following code requires the Enable AD Hoc distributed Queries server configuration option. Assuming the previous script found the problem, I created the script to send the message.

if  @mail  =  ' Y ' BEGIN declare  @msg  varchar (MAX)  =  ' replication on  '  + @ @SERVERNAME +  '  may be experiencing some problems. attempts  to restart the distribution agent have been made.  ' +  ' If  this is not the first message like this that you have
 received within the last hour, please investigate. ' declare  @body  nvarchar (max) declare  @xml1  nvarchar (max) declare  @tab1  nvarchar (max ) declare  @xml2  nvarchar (max) declare  @tab2  nvarchar (max) set  @xml1  = cast ((  SELECT subscriber AS  ' TD ', ',subscriber_db as  ' TD ', ', latency as  ' TD ' , ', pendingcmdcount as  ' TD ', ', estimatedprocesstime as  ' TD ' FROM ## Subscriptioninfo s FOR&NBSP;XML&NBsp PATH (' tr '), elements )  as nvarchar (MAX)) set  @tab1  = ' 

Finally, you need to periodically delete the data from the Replication state table so that the data is not too old.

DECLARE @delDate datetime = GETDATE () -10
DELETE from DBA.dbo.Replication_Que_History
WHERE logdate < @ Deldate

If any of the thresholds configured in the script match, the publishing agent associated with the subscription of the problematic counter will be restarted, and if it has stopped, the job will start. You will be notified of this action by email. In many cases, restarting the Distribution Agent resolves the issue, and the replication begins to work. If the problem is still not fixed, the next time the job runs the same action, another message is received. You need to start checking the situation.

You can call the 3rd script in your alarm system and restart the Distribution Agent job when any threshold matches. Or, run a 1th script to create the table. Create a new job, run the next 3 scripts in step 1th, and then place the 5th script in step 2nd. I currently run this schedule every 10 minutes.

This process is primarily intended to help deal with intermittent downtime of transactional replication. It is still important to monitor the replication process regularly using Replication Monitor. This process is just to stop phone harassment during off hours and can be repaired only by starting the Distribution Agent job.



This article is from the SQL Server deep Dive blog, so be sure to keep this source http://ultrasql.blog.51cto.com/9591438/1907283

Monitoring SQL Server Transactional replication

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.