July 14, 2005 at 5:48 am
On many occasions, I have been asked to find out if a table or table(s) are being replicated to various servers. This is a tedious task. Is there a way, using t-sql, that I can check if a table has been published for replication and get eh name of the publication as well as the subscribers of that publication? (BTW - I am new to the administration side of SQL Server but experienced in the programming side)
Kindest Regards,
David
** Obstacles are those frightening things that appear when we take our eyes off the goal. **
July 14, 2005 at 6:28 am
You can run the following and see if there is an article for a particular table, and if so, what the Publication name is (from the database in question):
select * from sysarticles
where Dest_Table =
There is also the syssubscriptions system table table - 'Contains one row for each subscription in the database. This table is stored in the publication database.'
July 14, 2005 at 6:44 am
So the sql:
select * from sysarticles where Dest_Table = <table> and select * from syssubscriptions where artid=<artid from previous> will tell me if the table is published and has a subscriber.
I assume there will one record for each subscriber for that publication or is it only one entry period? What other tables can be used to make this information less cryptic. IE What is the actual server subscribing to the publication. For example, table one is being transactionally replicated as a push. Server A and B are subscribers to this publication. I want to show <publication name> is pushing data from <table name> to server <server name>.
Kindest Regards,
David
** Obstacles are those frightening things that appear when we take our eyes off the goal. **
July 15, 2005 at 11:58 am
I created a few utilities for my own use to list what tables are being replicated, including filter data, and also to verify that the record counts on the publisher & the subscriber are the same (or close due to latency). Let me know if you'd like some examples.
July 15, 2005 at 12:00 pm
That would be good. I will take whatever you have to offer.
Kindest Regards,
David
** Obstacles are those frightening things that appear when we take our eyes off the goal. **
July 15, 2005 at 3:11 pm
and if the replicated data was done with merge then have alook at
sp_validatemergepulication and sp_validatemergesubscription
or if it is transactional or snapshot:
sp_publication_validation may prove usefull
* Noel
July 18, 2005 at 12:04 pm
Here's what I run to build replication info into a table, and verify the counts between publisher & subscriber.
I use the "replication_stats" table for reference whenever I want to see what's being replicated. It's simpler than waiting for Publication properties to display one at a time.
Disclaimer: I quickly gathered this together & "genericized" some of it, so let me know if it seems something's missing or not clear.
++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- GET REPLICATION INFO & VERIFY COUNTS BETWEEN PUBLISHER & SUBSCRIBER
-- All Tables & SPs are created in my "Utility" database, not a production DB
-- Shows statistics of replicated tables.
CREATE TABLE [dbo].[Replication_Stats] (
[name] [nvarchar] (128) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[publisher_db] [nvarchar] (128) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[description] [nvarchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[filter_clause] [ntext] COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[artid] [int] NOT NULL ,
[objid] [int] NOT NULL ,
[pubid] [int] NOT NULL ,
[dest_db] [nvarchar] (128) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[publisher_server] [char] (15) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[dest_server] [char] (15) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
-------------==========================================================================================
-- Shows counts of records in replicated tables
CREATE TABLE [dbo].[Replication_Counts] (
[Rep_Table] [char] (40) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[Rep_DB_Pub] [char] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[Rep_DB_Pub#] [int] NULL ,
[Rep_DB_Sub] [char] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[Rep_DB_Sub#] [int] NULL ,
[Rep_Count_Date] [datetime] NULL ,
[Rep_Filter_Clause] [varchar] (500) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[Rep_Pub_Server] [char] (15) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[Rep_Sub_Server] [char] (15) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Replication_Counts] ADD
CONSTRAINT [DF_Replication_Counts_Rep_Filter_Clause] DEFAULT (' ') FOR [Rep_Filter_Clause]
GO
-------------===========================================================================================
-- Shows record count discrepancy between publisher & subscriber
CREATE TABLE [dbo].[replication_mismatches] (
[Rep_Table] [char] (40) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[Rep_DB_Pub] [char] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[Rep_DB_Pub#] [int] NULL ,
[Rep_DB_Sub] [char] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[Rep_DB_Sub#] [int] NULL ,
[Rep_Count_Date] [datetime] NULL ,
[Rep_Filter_Clause] [varchar] (500) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[Rep_Pub_Server] [char] (15) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[Rep_Sub_Server] [char] (15) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]
GO
-------------============================================================================================
-- >>>>>>>>>>>>>>>>>>>>>>>>>>> STEP 1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<
--Build Replication_Stats from system replication info. (I run this, along w/ other unrelated stuff, as a DTS, which is Step 1 in my nightly job)
truncate table Utility_DB_NameHere.dbo.Replication_Stats
-- Insert PRD Replication info
insert into Utility_DB_NameHere.dbo.Replication_Stats
select art.name, publisher_db,
pub.description, filter_clause,
art.artid, objid, art.pubid ,sub.dest_db, 'PUBLISHER_SERVERNAME_HERE', 'SUBSCRIBER_SERVERNAME_HERE'
from Publisher_DB_NameHere.dbo.sysarticles art
join "distribution"."dbo".MSarticles msart on name = article
and msart.article_id = art.artid
join Publisher_DB_NameHere.dbo.syspublications pub
on pub.pubid = art.pubid
join Publisher_DB_NameHere.dbo.syssubscriptions sub on art.artid = sub.artid and srvid = 2
order by art.name
-------------============================================================================================
-- >>>>>>>>>>>>>>>>>>>>>>>>>>> STEP 2 <<<<<<<<<<<<<<<<<<<<<<<<<<<<
-- This sp gets the counts of the replicated table from the publisher ( Production) based on any filter, and gets the count from the subscriber
--and puts a record in table replication_counts. Later, another job can run to look at the 2 counts and see if they are the same or not
-- (They should be close, depending on frequency of replication)
-- I don't truncate "replication_counts" because I thought I may want history
CREATE procedure sp_ReplicationCounts as
-- temp table holds the select statements to be executed
create table #select_statements
(statement_id int identity(1,1) not null,
statement_text varchar(4000))
-- the INSERT to the temp table R1
insert into #select_statements
select 'insert into UtilityDBNameHere.dbo.replication_counts select '''+ [name] + ''','''
+ publisher_db + ''',(select count(*) from '
+ publisher_db + '.dbo.' + [name] + ' with (nolock) '
+ case
WHEN filter_clause IS not NULL THEN ' where ' + rtrim(convert(varchar(500),filter_clause)) + '), '''
ELSE '), '''
end
+ dest_db + ''',(select * from openrowset (''SQLOLEDB'',''SUBSCRIBER_SERVERNAME_HERE'';''YOUR_SQL_LOGIN'';''YOUR_LOGIN_PASSWORD'','' select count(*) from '
+ dest_db + '.dbo.' + [name] + ' with (nolock) ' + ''')), getdate(), ''''' + ' ,''' + rtrim(publisher_server) + '''' + ' ,''' + rtrim(dest_server) + ''''-- blank in field after getdate to be updated later w/ filter clause details
from Utility_DB_NameHere.dbo.replication_stats
where publisher_server = 'PUBLISHER_SERVERNAME_HERE'
-- the statement execution
set nocount on
declare @statement_text varchar(4000),
@i int,
@rows int
select @rows = count(*) from #select_statements
select @i = @rows
declare statement_cur cursor for
select statement_text
from #select_statements
order by statement_id
open statement_cur
fetch next from statement_cur
into @statement_text
while @@FETCH_STATUS = 0
begin
exec (@statement_text)
fetch next from statement_cur
into @statement_text
set @i = (@i - 1)
end
close statement_cur
deallocate statement_cur
-- Update Replication_Counts with filter information
update Utility_DB_NameHere.dbo.replication_counts set rep_filter_clause = rtrim(convert(varchar(500),Utility_DB_NameHere.dbo.replication_stats.filter_clause))
from Utility_DB_NameHere.dbo.replication_stats
where name = rep_table and dest_db = rep_db_sub and publisher_db = rep_db_pub
and publisher_server = 'PUBLISHER_SERVERNAME_HERE'
-- cleanup
drop table #select_statements
set nocount off
GO
-------------============================================================================================
-- >>>>>>>>>>>>>>>>>>>>>>>>>>> STEP 3 <<<<<<<<<<<<<<<<<<<<<<<<<<<<
-- Identify discrepancies between records counts on PRD and record counts in replicated tables, taking filer clause(s) into account.
-- Drop & recreate mismatch table with new data if there are records in Replication_Counts
CREATE PROCEDURE tp_Replication_Mismatches AS
SELECT *
FROM Replication_Counts
WHERE (CONVERT(char(10),Rep_Count_Date,101) = CONVERT(char(10),getDate(),101)) AND (Rep_DB_Pub# <> Rep_DB_Sub#) OR
(CONVERT(char(10),Rep_Count_Date,101) = CONVERT(char(10),getDate(),101)) AND (Rep_DB_Pub# <> Rep_DB_Sub#)
ORDER BY rep_db_sub, rep_table, rep_count_date
IF @@ROWCOUNT > 0
begin
drop table replication_mismatches
SELECT *
into replication_mismatches
FROM Replication_Counts
WHERE (CONVERT(char(10),Rep_Count_Date,101) = CONVERT(char(10),getDate(),101)) AND (Rep_DB_Pub# <> Rep_DB_Sub#) OR
(CONVERT(char(10),Rep_Count_Date,101) = CONVERT(char(10),getDate(),101)) AND (Rep_DB_Pub# <> Rep_DB_Sub#)
ORDER BY rep_db_sub, rep_table, rep_count_date
end
GO
Viewing 7 posts - 1 through 6 (of 6 total)
You must be logged in to reply to this topic. Login to reply