Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 Script Library
 Monitor transactional replication latency

Author  Topic 

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2008-06-12 : 07:07:20
[code]CREATE PROCEDURE [dbo].[proc_replication_latency_monitor]
AS

-- Procedure created by Henning Frettem (Lumbago), www.sqlteam.com, 12th of June 2008

BEGIN

SET NOCOUNT ON

DECLARE
@PublishedDBName varchar(200),
@SQL nvarchar(2000),
@PublicationPK int,
@PublicationName varchar(200),
@PublicationDatabase varchar(200),
@TracerTokenID int,
@Parmameters nvarchar(500)

DECLARE @Publications table (
PublicationPK int IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
PublicationDatabase varchar(200),
PublicationName varchar(200),
TracerTokenID int,
TracerTokenPostTime datetime
)

DECLARE @Latency table (
PublicationPK int,
DistributorLatency bigint,
Subscriber sysname,
SubscriberDB sysname,
SubscriberLatency bigint,
OverallLatency bigint
)

--> Cursor for fetching all publications in all databases
DECLARE curPublishedDatabases CURSOR LOCAL FAST_FORWARD FOR
SELECT [name] FROM sys.databases WHERE is_published > 0

OPEN curPublishedDatabases
FETCH curPublishedDatabases INTO @PublishedDBName
WHILE @@FETCH_STATUS = 0
BEGIN
SET @SQL = N'SELECT ''' + @PublishedDBName + ''', [name] FROM ' + @PublishedDBName + '.dbo.syspublications'
INSERT INTO @Publications (PublicationDatabase, PublicationName)
EXEC sp_executesql @SQL

FETCH NEXT FROM curPublishedDatabases INTO @PublishedDBName
END

CLOSE curPublishedDatabases
DEALLOCATE curPublishedDatabases

--> Cursor for posting tracer tokens
DECLARE curPublications CURSOR LOCAL FAST_FORWARD FOR
SELECT PublicationPK, PublicationDatabase, PublicationName FROM @Publications

OPEN curPublications
FETCH curPublications INTO @PublicationPK, @PublicationDatabase, @PublicationName
WHILE @@FETCH_STATUS = 0
BEGIN
SET @Parmameters = N'@PublicationName varchar(200), @TracerTokenID_OUT int OUTPUT';
SET @SQL = N'EXEC ' + @PublicationDatabase + '.sys.sp_posttracertoken @publication = @PublicationName, @tracer_token_id = @TracerTokenID_OUT OUTPUT'
EXEC sp_executesql @SQL, @Parmameters, @PublicationName = @PublicationName, @TracerTokenID_OUT = @TracerTokenID OUTPUT

UPDATE @Publications SET
TracerTokenID = @TracerTokenID,
TracerTokenPostTime = GETDATE()
WHERE PublicationPK = @PublicationPK

FETCH NEXT FROM curPublications INTO @PublicationPK, @PublicationDatabase, @PublicationName
END
CLOSE curPublications
DEALLOCATE curPublications

--> Wait two minutes for all tokens to be commited at all subscribers
WAITFOR DELAY '000:02:00.000'

--> Then check the results for each posted token
DECLARE curTokens CURSOR LOCAL FAST_FORWARD FOR
SELECT PublicationPK, PublicationDatabase, PublicationName, TracerTokenID FROM @Publications

OPEN curTokens
FETCH curTokens INTO @PublicationPK, @PublicationDatabase, @PublicationName, @TracerTokenID
WHILE @@FETCH_STATUS = 0
BEGIN
--> Insert token history for each token
SET @SQL = N'EXEC ' + @PublicationDatabase + '.dbo.sp_helptracertokenhistory @publication = ''' + @PublicationName + ''', @tracer_id = ' + CAST(@TracerTokenID AS VARCHAR(50)) + ''
INSERT INTO @Latency
(DistributorLatency, Subscriber, SubscriberDB, SubscriberLatency, OverallLatency)
EXEC sp_executesql @SQL

--> Make sure that the PublicationPK is added to the token history
UPDATE @Latency SET PublicationPK = @PublicationPK WHERE PublicationPK IS NULL

--> Clean up the tracer token
SET @SQL = N'EXEC ' + @PublicationDatabase + '.sys.sp_deletetracertokenhistory @publication = ''' + @PublicationName + ''', @tracer_id = ' + CAST(@TracerTokenID AS VARCHAR(50)) + ''
EXEC sp_executesql @SQL

FETCH NEXT FROM curTokens INTO @PublicationPK, @PublicationDatabase, @PublicationName, @TracerTokenID
END
CLOSE curTokens
DEALLOCATE curTokens

SELECT
b.PublicationDatabase,
b.PublicationName,
a.Subscriber,
a.SubscriberDB,
a.OverallLatency,
b.TracerTokenPostTime
FROM @Latency a
INNER JOIN @Publications b
ON a.PublicationPK = b.PublicationPK

END[/code]

--
Lumbago

rsbutterfly16
Starting Member

6 Posts

Posted - 2010-01-25 : 01:56:17
hi this is a wonderful script , would there be any way to run this script without inserting a token? i already have a job that inserts a token every minute.
Go to Top of Page

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2010-01-25 : 03:38:30
Yes, you can use the system stored procedure sp_helptracertokens to obtain the tracer_id which in my script is the TracerTokenID...that's basically what you need.

- Lumbago
http://xkcd.com/327/
Go to Top of Page

rsbutterfly16
Starting Member

6 Posts

Posted - 2010-01-25 : 15:54:24
quote:
Originally posted by Lumbago

Yes, you can use the system stored procedure sp_helptracertokens to obtain the tracer_id which in my script is the TracerTokenID...that's basically what you need.

- Lumbago
http://xkcd.com/327/



thank you for your fast reply, i tried to use it but i get no results, i need to be able to get information from the last token inserted since if there is latency there could be a lot of tokens inserted since they get inserted every minute.

here is what i have so far but no luck


CREATE PROCEDURE [dbo].[proc_replication_latency_monitor]
AS

-- Procedure created by Henning Frettem (Lumbago), www.sqlteam.com, 12th of June 2008

BEGIN

SET NOCOUNT ON

DECLARE
@PublishedDBName varchar(200),
@SQL nvarchar(2000),
@PublicationPK int,
@PublicationName varchar(200),
@PublicationDatabase varchar(200),
@TracerTokenID int,
@Parmameters nvarchar(500),
@tokenID INT;

DECLARE @Publications table (
PublicationPK int IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
PublicationDatabase varchar(200),
PublicationName varchar(200),
TracerTokenID int,
TracerTokenPostTime datetime
)

DECLARE @Latency table (
PublicationPK int,
DistributorLatency bigint,
Subscriber sysname,
SubscriberDB sysname,
SubscriberLatency bigint,
OverallLatency bigint
)

--> Cursor for fetching all publications in all databases
DECLARE curPublishedDatabases CURSOR LOCAL FAST_FORWARD FOR
SELECT [name] FROM sys.databases WHERE is_published > 0

OPEN curPublishedDatabases
FETCH curPublishedDatabases INTO @PublishedDBName
WHILE @@FETCH_STATUS = 0
BEGIN
SET @SQL = N'SELECT ''' + @PublishedDBName + ''', [name] FROM ' + @PublishedDBName + '.dbo.syspublications'
INSERT INTO @Publications (PublicationDatabase, PublicationName)
EXEC sp_executesql @SQL

FETCH NEXT FROM curPublishedDatabases INTO @PublishedDBName
END

CLOSE curPublishedDatabases
DEALLOCATE curPublishedDatabases

--> Cursor for posting tracer tokens
DECLARE curPublications CURSOR LOCAL FAST_FORWARD FOR
SELECT PublicationPK, PublicationDatabase, PublicationName FROM @Publications

OPEN curPublications
FETCH curPublications INTO @PublicationPK, @PublicationDatabase, @PublicationName
WHILE @@FETCH_STATUS = 0
BEGIN
--SET @Parmameters = N'@PublicationName varchar(200), @TracerTokenID_OUT int OUTPUT';
-- SET @SQL = N'EXEC ' + @PublicationDatabase + '.sys.sp_posttracertoken @publication = @PublicationName, @tracer_token_id = @TracerTokenID_OUT OUTPUT'



CREATE TABLE #tokens (tracer_id int, publisher_commit datetime)

-- Return only last inserted tracer token information to a temp table.
INSERT #tokens (tracer_id, publisher_commit)
EXEC sys.sp_helptracertokens @publication = @PublicationName;
SET @tokenID = (SELECT TOP 1 tracer_id FROM #tokens
ORDER BY publisher_commit DESC)

SET @SQL = N'EXEC ' + @PublicationDatabase + '.sys.sp_helptracertokens @publication = @PublicationName,
@tracer_id = @tokenID'



EXEC sp_executesql @SQL, @Parmameters, @PublicationName = @PublicationName, @tracer_id = @TracerTokenID OUTPUT

UPDATE @Publications SET
TracerTokenID = @TracerTokenID,
TracerTokenPostTime = GETDATE()
WHERE PublicationPK = @PublicationPK

FETCH NEXT FROM curPublications INTO @PublicationPK, @PublicationDatabase, @PublicationName
END
CLOSE curPublications
DEALLOCATE curPublications

--> Wait two minutes for all tokens to be commited at all subscribers
--WAITFOR DELAY '000:02:00.000'

--> Then check the results for each posted token
DECLARE curTokens CURSOR LOCAL FAST_FORWARD FOR
SELECT PublicationPK, PublicationDatabase, PublicationName, TracerTokenID FROM @Publications

OPEN curTokens
FETCH curTokens INTO @PublicationPK, @PublicationDatabase, @PublicationName, @TracerTokenID
WHILE @@FETCH_STATUS = 0
BEGIN
--> Insert token history for each token
SET @SQL = N'EXEC ' + @PublicationDatabase + '.dbo.sp_helptracertokenhistory @publication = ''' + @PublicationName + ''', @tracer_id = ' + CAST(@TracerTokenID AS VARCHAR(50)) + ''
INSERT INTO @Latency
(DistributorLatency, Subscriber, SubscriberDB, SubscriberLatency, OverallLatency)
EXEC sp_executesql @SQL

--> Make sure that the PublicationPK is added to the token history
UPDATE @Latency SET PublicationPK = @PublicationPK WHERE PublicationPK IS NULL
/*
--> Clean up the tracer token
SET @SQL = N'EXEC ' + @PublicationDatabase + '.sys.sp_deletetracertokenhistory @publication = ''' + @PublicationName + ''', @tracer_id = ' + CAST(@TracerTokenID AS VARCHAR(50)) + ''
EXEC sp_executesql @SQL
*/
FETCH NEXT FROM curTokens INTO @PublicationPK, @PublicationDatabase, @PublicationName, @TracerTokenID
END
CLOSE curTokens
DEALLOCATE curTokens

SELECT
b.PublicationDatabase,
b.PublicationName,
a.Subscriber,
a.SubscriberDB,
a.OverallLatency,
b.TracerTokenPostTime
FROM @Latency a
INNER JOIN @Publications b
ON a.PublicationPK = b.PublicationPK

END



Go to Top of Page

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2010-01-26 : 03:16:07
Well...the problem is that I created this script in a previous job and right now I don't have any replication set up anywhere that I can test on. But I did som small changes to the procedure you posted, see if you can make any sense of it...
CREATE PROCEDURE [dbo].[proc_replication_latency_monitor]
AS

-- Procedure created by Henning Frettem (Lumbago), www.sqlteam.com, 12th of June 2008

BEGIN

SET NOCOUNT ON

DECLARE
@PublishedDBName varchar(200),
@SQL nvarchar(2000),
@PublicationPK int,
@PublicationName varchar(200),
@PublicationDatabase varchar(200),
@TracerTokenID int,
@Parmameters nvarchar(500),
@tokenID INT;

DECLARE @Publications table (
PublicationPK int IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
PublicationDatabase varchar(200),
PublicationName varchar(200),
TracerTokenID int,
TracerTokenPostTime datetime
)

DECLARE @Latency table (
PublicationPK int,
DistributorLatency bigint,
Subscriber sysname,
SubscriberDB sysname,
SubscriberLatency bigint,
OverallLatency bigint
)

--> Cursor for fetching all publications in all databases
DECLARE curPublishedDatabases CURSOR LOCAL FAST_FORWARD FOR
SELECT [name] FROM sys.databases WHERE is_published > 0

OPEN curPublishedDatabases
FETCH curPublishedDatabases INTO @PublishedDBName
WHILE @@FETCH_STATUS = 0
BEGIN
SET @SQL = N'SELECT ''' + @PublishedDBName + ''', [name] FROM ' + @PublishedDBName + '.dbo.syspublications'
INSERT INTO @Publications (PublicationDatabase, PublicationName)
EXEC sp_executesql @SQL

FETCH NEXT FROM curPublishedDatabases INTO @PublishedDBName
END

CLOSE curPublishedDatabases
DEALLOCATE curPublishedDatabases

CREATE TABLE #tokens (tracer_id int, publisher_commit datetime)

--> Cursor for posting tracer tokens
DECLARE curPublications CURSOR LOCAL FAST_FORWARD FOR
SELECT PublicationPK, PublicationDatabase, PublicationName FROM @Publications

OPEN curPublications
FETCH curPublications INTO @PublicationPK, @PublicationDatabase, @PublicationName
WHILE @@FETCH_STATUS = 0
BEGIN
--SET @Parmameters = N'@PublicationName varchar(200), @TracerTokenID_OUT int OUTPUT';
-- SET @SQL = N'EXEC ' + @PublicationDatabase + '.sys.sp_posttracertoken @publication = @PublicationName, @tracer_token_id = @TracerTokenID_OUT OUTPUT'


-- Return only last inserted tracer token information to a temp table.
INSERT #tokens (tracer_id, publisher_commit)
EXEC sys.sp_helptracertokens @publication = @PublicationName;
SET @tokenID = (SELECT TOP 1 tracer_id FROM #tokens ORDER BY publisher_commit DESC)

SET @SQL = N'EXEC ' + @PublicationDatabase + '.sys.sp_helptracertokens @publication = ''' + @PublicationName + ''', @tracer_id = ' + @tokenID

EXEC sp_executesql @SQL, @Parmameters, @PublicationName = @PublicationName, @tracer_id = @TracerTokenID OUTPUT

UPDATE @Publications SET
TracerTokenID = @TracerTokenID,
TracerTokenPostTime = GETDATE()
WHERE PublicationPK = @PublicationPK

FETCH NEXT FROM curPublications INTO @PublicationPK, @PublicationDatabase, @PublicationName
END
CLOSE curPublications
DEALLOCATE curPublications

--> Wait two minutes for all tokens to be commited at all subscribers
--WAITFOR DELAY '000:02:00.000'

--> Then check the results for each posted token
DECLARE curTokens CURSOR LOCAL FAST_FORWARD FOR
SELECT PublicationPK, PublicationDatabase, PublicationName, TracerTokenID FROM @Publications

OPEN curTokens
FETCH curTokens INTO @PublicationPK, @PublicationDatabase, @PublicationName, @TracerTokenID
WHILE @@FETCH_STATUS = 0
BEGIN
--> Insert token history for each token
[SET @SQL = N'EXEC ' + @PublicationDatabase + '.dbo.sp_helptracertokenhistory @publication = ''' + @PublicationName + ''', @tracer_id = ' + CAST(@TracerTokenID AS VARCHAR(50)) + ''
INSERT INTO @Latency
(DistributorLatency, Subscriber, SubscriberDB, SubscriberLatency, OverallLatency)
EXEC sp_executesql @SQL

--> Make sure that the PublicationPK is added to the token history
UPDATE @Latency SET PublicationPK = @PublicationPK WHERE PublicationPK IS NULL
/*
--> Clean up the tracer token
SET @SQL = N'EXEC ' + @PublicationDatabase + '.sys.sp_deletetracertokenhistory @publication = ''' + @PublicationName + ''', @tracer_id = ' + CAST(@TracerTokenID AS VARCHAR(50)) + ''
EXEC sp_executesql @SQL
*/
FETCH NEXT FROM curTokens INTO @PublicationPK, @PublicationDatabase, @PublicationName, @TracerTokenID
END
CLOSE curTokens
DEALLOCATE curTokens

DROP TABLE #tokens

SELECT
b.PublicationDatabase,
b.PublicationName,
a.Subscriber,
a.SubscriberDB,
a.OverallLatency,
b.TracerTokenPostTime
FROM @Latency a
INNER JOIN @Publications b
ON a.PublicationPK = b.PublicationPK

END


- Lumbago
If the facts don't fit the theory, change the facts. Albert Einstein
Go to Top of Page

rsbutterfly16
Starting Member

6 Posts

Posted - 2010-01-26 : 16:03:58
thank you!! i get an error message
Msg 8146, Level 16, State 1, Procedure

proc_replication_latency_monitor, Line 0
Procedure proc_replication_latency_monitor has no parameters and arguments were supplied.
Go to Top of Page

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2010-01-27 : 05:07:06
I'm sorry but I don't have any replication set up here so I'm unable to test. What have you done to debug the procedure?

- Lumbago
If the facts don't fit the theory, change the facts. Albert Einstein
Go to Top of Page

rsbutterfly16
Starting Member

6 Posts

Posted - 2010-01-27 : 19:10:31
hi i got working but it does not show me the latency as the replication monitor and some of them null. this is my output:

PublicationDatabase PublicationName Subscriber SubscriberDB Latency TracerTakenPostTime
Students Students Server\StudentsMS Students 7 59:36.1
Students Students Server\Reports1 StudentRP1 NULL 59:36.1
Students Students Server\Reports2 StudentRP1 NULL 59:36.1
Students StudentsRP Server\Reports3 Students NULL 59:36.4
Students DW Server\DataWarehouse Students 4 59:36.9
Students C2KOnline1 Server\Distributors Students 7 59:37.2

but my latency is around one hour and a half :(


CREATE PROCEDURE [dbo].[proc_replication_latency_monitor]
AS
-- Procedure created by Henning Frettem (Lumbago), www.sqlteam.com, 12th of June 2008

BEGIN

SET NOCOUNT ON

DECLARE
@PublishedDBName varchar(200),
@SQL nvarchar(2000),
@PublicationPK int,
@PublicationName varchar(200),
@PublicationDatabase varchar(200),
@TracerTokenID int,
@Parmameters nvarchar(500),
@tokenID INT;

DECLARE @Publications table (
PublicationPK int IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
PublicationDatabase varchar(200),
PublicationName varchar(200),
TracerTokenID int,
TracerTokenPostTime datetime
)

DECLARE @Latency table (
PublicationPK int,
DistributorLatency bigint,
Subscriber sysname,
SubscriberDB sysname,
SubscriberLatency bigint,
OverallLatency bigint
)

--> Cursor for fetching all publications in all databases
DECLARE curPublishedDatabases CURSOR LOCAL FAST_FORWARD FOR
SELECT [name] FROM sys.databases WHERE is_published > 0

OPEN curPublishedDatabases
FETCH curPublishedDatabases INTO @PublishedDBName
WHILE @@FETCH_STATUS = 0
BEGIN
SET @SQL = N'SELECT ''' + @PublishedDBName + ''', [name] FROM ' + @PublishedDBName + '.dbo.syspublications'
INSERT INTO @Publications (PublicationDatabase, PublicationName)
EXEC sp_executesql @SQL

FETCH NEXT FROM curPublishedDatabases INTO @PublishedDBName
END

CLOSE curPublishedDatabases
DEALLOCATE curPublishedDatabases

CREATE TABLE #tokens (tracer_id int, publisher_commit datetime)

--> Cursor for posting tracer tokens
DECLARE curPublications CURSOR LOCAL FAST_FORWARD FOR
SELECT PublicationPK, PublicationDatabase, PublicationName FROM @Publications

OPEN curPublications
FETCH curPublications INTO @PublicationPK, @PublicationDatabase, @PublicationName
WHILE @@FETCH_STATUS = 0
BEGIN
--SET @Parmameters = N'@PublicationName varchar(200), @TracerTokenID_OUT int OUTPUT';
-- SET @SQL = N'EXEC ' + @PublicationDatabase + '.sys.sp_posttracertoken @publication = @PublicationName, @tracer_token_id = @TracerTokenID_OUT OUTPUT'


-- Return only last inserted tracer token information to a temp table.
INSERT #tokens (tracer_id, publisher_commit)
EXEC sys.sp_helptracertokens @publication = @PublicationName;
SET @tokenID = (SELECT TOP 1 tracer_id FROM #tokens ORDER BY publisher_commit DESC)


SET @Parmameters = N'@PublicationName varchar(200), @tokenID int OUTPUT';
--SET @SQL = N'EXEC ' + @PublicationDatabase + '.sys.sp_helptracertokens @publication = ''' + @PublicationName + ''', @tracer_id = ' + @tokenID--@tracer_id is not a valid parameter for this sp
--SET @SQL = N'EXEC ' + @PublicationDatabase + '.sys.sp_helptracertokens @publication = ''' + @PublicationName + ''', @tracer_id = ' + CAST(@tokenID AS VARCHAR(50)) + ''
SET @SQL = N'EXEC ' + @PublicationDatabase + '.sys.sp_helptracertokens @publication = ''' + @PublicationName + ''''

--EXEC sp_executesql @SQL, @Parmameters, @PublicationName = @PublicationName, @tracer_id = @TracerTokenID OUTPUT
EXEC sp_executesql @SQL, @Parmameters, @PublicationName = @PublicationName, @tracer_id = @TokenID OUTPUT

UPDATE @Publications SET
TracerTokenID = @TokenID,
TracerTokenPostTime = GETDATE()
WHERE PublicationPK = @PublicationPK

FETCH NEXT FROM curPublications INTO @PublicationPK, @PublicationDatabase, @PublicationName
END
CLOSE curPublications
DEALLOCATE curPublications


--> Then check the results for each posted token
DECLARE curTokens CURSOR LOCAL FAST_FORWARD FOR
SELECT PublicationPK, PublicationDatabase, PublicationName, TracerTokenID FROM @Publications

OPEN curTokens
FETCH curTokens INTO @PublicationPK, @PublicationDatabase, @PublicationName, @TracerTokenID
WHILE @@FETCH_STATUS = 0
BEGIN
--> Insert token history for each token
SET @SQL = N'EXEC ' + @PublicationDatabase + '.dbo.sp_helptracertokenhistory @publication = ''' + @PublicationName + ''', @tracer_id = ' + CAST(@TracerTokenID AS VARCHAR(50)) + ''
--SET @SQL = N'EXEC ' + @PublicationDatabase + '.dbo.sp_helptracertokenhistory @publication = ''' + @PublicationName + ''', @tracer_id = ' + CAST(@TokenID AS VARCHAR(50)) + ''


INSERT INTO @Latency
(DistributorLatency, Subscriber, SubscriberDB, SubscriberLatency, OverallLatency)
EXEC sp_executesql @SQL

--> Make sure that the PublicationPK is added to the token history
UPDATE @Latency SET PublicationPK = @PublicationPK WHERE PublicationPK IS NULL
/*
--> Clean up the tracer token
SET @SQL = N'EXEC ' + @PublicationDatabase + '.sys.sp_deletetracertokenhistory @publication = ''' + @PublicationName + ''', @tracer_id = ' + CAST(@TracerTokenID AS VARCHAR(50)) + ''
EXEC sp_executesql @SQL
*/
FETCH NEXT FROM curTokens INTO @PublicationPK, @PublicationDatabase, @PublicationName, @TracerTokenID
END
CLOSE curTokens
DEALLOCATE curTokens

DROP TABLE #tokens

SELECT
b.PublicationDatabase,
b.PublicationName,
a.Subscriber,
a.SubscriberDB,
a.OverallLatency as LatencyA,
CONVERT(VARCHAR(8), DATEADD(ss, a.OverallLatency, 0) ,114),
b.TracerTokenPostTime
FROM @Latency a
INNER JOIN @Publications b
ON a.PublicationPK = b.PublicationPK

END
Go to Top of Page
   

- Advertisement -