<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SQL Fool &#187; replication</title>
	<atom:link href="http://sqlfool.com/tag/replication/feed/" rel="self" type="application/rss+xml" />
	<link>http://sqlfool.com</link>
	<description>Adventures in SQL Tuning - a blog for the rest of us</description>
	<lastBuildDate>Fri, 16 Jul 2010 14:34:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Replication Bug with Partitioned Tables</title>
		<link>http://sqlfool.com/2009/11/replication-bug-with-partitioned-tables/</link>
		<comments>http://sqlfool.com/2009/11/replication-bug-with-partitioned-tables/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 14:48:54 +0000</pubDate>
		<dc:creator>Michelle Ufford</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[SQL Tips]]></category>
		<category><![CDATA[Syndication]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[partitioning]]></category>
		<category><![CDATA[replication]]></category>
		<category><![CDATA[SQL Server 2005]]></category>

		<guid isPermaLink="false">http://sqlfool.com/?p=1290</guid>
		<description><![CDATA[Recently, we came across a bug in SQL Server 2005 on one of our production servers. Apparently, if you execute an ALTER TABLE statement on a replicated table with more than 128 partitions, the log reader will fail. A relatively obscure bug, I know. Microsoft has recognized this as a confirmed bug, but I couldn't [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, we came across a bug in SQL Server 2005 on one of our production servers.  Apparently, if you execute an ALTER TABLE statement on a replicated table with more than 128 partitions, the log reader will fail.  A relatively obscure bug, I know.  Microsoft has recognized this as a confirmed bug, but I couldn't find it anywhere on the intertubes, thus the inspiration for this blog post.  Microsoft's official solution for this issue is to upgrade to SQL Server 2008.  </p>
<p>For various reasons, we were unable to execute an upgrade at the time.  And since this was a 2 terabyte database, we wanted to come up with a solution that wouldn't involve reinitializing the entire publication.  Our quick-fix while we were troubleshooting the issue was to create a <a href="http://msdn.microsoft.com/en-us/library/ms188279.aspx" target="_blank">linked server</a> to the production box.  Not ideal, I know, but it worked in a pinch and minimized exposure of the issue.  Fortunately for us, we were able to solve the problem on the publication database pretty easily.  All of the affected partition functions had empty partitions created several months in the future, so we simply <a href="http://msdn.microsoft.com/en-us/library/ms186307.aspx" target="_blank">merged any empty partition ranges</a> for future dates.  Our solution to our now-out-of-date subscribers was to apply <a href="http://msdn.microsoft.com/en-us/library/ms151775.aspx" target="_blank">static row filtering</a> to any table with more than 100 million records.  While this would introduce some overhead with the replication of these tables, it would allow us a much faster recovery time.  We decided to use the start of the most recent hour as our filtering criteria, just to give us a "clean" filter, so we had to delete data from any table where we were going to apply the filter.  After that, it was simply a matter of resuming replication.  </p>
<p>All things considered, it took us a little over a day to recover from the issue.  Most of that time was spent troubleshooting the problem and identifying a workable solution; actual execution of the changes was pretty quick.  Moral of the story?  Upgrade to SQL Server 2008.  <img src='http://sqlfool.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://sqlfool.com/2009/11/replication-bug-with-partitioned-tables/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fragmentation on Replicated Tables</title>
		<link>http://sqlfool.com/2009/01/fragmentation-on-replicated-tables/</link>
		<comments>http://sqlfool.com/2009/01/fragmentation-on-replicated-tables/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 15:27:50 +0000</pubDate>
		<dc:creator>Michelle Ufford</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Performance & Tuning]]></category>
		<category><![CDATA[SQL Tips]]></category>
		<category><![CDATA[Syndication]]></category>
		<category><![CDATA[fragmentation]]></category>
		<category><![CDATA[indexes]]></category>
		<category><![CDATA[replication]]></category>

		<guid isPermaLink="false">http://sqlfool.com/?p=351</guid>
		<description><![CDATA[I've heard more than one person state that they do not need to defrag their tables, because they're replicated and the source tables are defragged regularly. Let's set this myth straight. Repeat after me: defragmentation processes are not replicated. Good. Thank you. For those non-believers, let me prove it: SET NOCOUNT ON; &#160; /* Create [...]]]></description>
			<content:encoded><![CDATA[<p>I've heard more than one person state that they do not need to defrag their tables, because they're replicated and the source tables are defragged regularly.  Let's set this myth straight.</p>
<p>Repeat after me: <strong>defragmentation processes are not replicated.  </strong></p>
<p>Good.  Thank you.</p>
<p>For those non-believers, let me prove it:</p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span>;
&nbsp;
<span style="color: #008080;">/* Create publication db */</span>
<span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">DATABASE</span> sandbox_publisher;
GO
&nbsp;
<span style="color: #008080;">/* Create subscription db */</span>
<span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">DATABASE</span> sandbox_subscriber;
GO
&nbsp;
<span style="color: #008080;">/* Navigate to publisher db */</span>
<span style="color: #0000FF;">USE</span> sandbox_publisher;
GO
&nbsp;
<span style="color: #008080;">/* Create a table to play with */</span>
<span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">TABLE</span> myTable
<span style="color: #808080;">&#40;</span>
      myID <span style="color: #0000FF;">UNIQUEIDENTIFIER</span>
    , myColumn <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">2000</span><span style="color: #808080;">&#41;</span>
&nbsp;
    <span style="color: #0000FF;">CONSTRAINT</span> PK_myTable <span style="color: #0000FF;">PRIMARY</span> <span style="color: #0000FF;">KEY</span> <span style="color: #0000FF;">CLUSTERED</span> <span style="color: #808080;">&#40;</span>myID<span style="color: #808080;">&#41;</span>
<span style="color: #808080;">&#41;</span>;
<span style="color: #008080;">/* NOTE: please never, ever use this
   type of clustered index in real-life.
   The whole purpose is to generate
   substantial fragmentation for 
   illustrative purposes. */</span>
&nbsp;
<span style="color: #008080;">/* Populate it with some non-sequential
   records to generate fragmentation */</span>
<span style="color: #0000FF;">DECLARE</span> @iteration <span style="color: #0000FF;">INT</span>;
<span style="color: #0000FF;">SET</span> @iteration <span style="color: #808080;">=</span> <span style="color: #000;">0</span>;
&nbsp;
<span style="color: #0000FF;">WHILE</span> @iteration <span style="color: #808080;">&lt;</span> <span style="color: #000;">1000</span>
<span style="color: #0000FF;">BEGIN</span>
    <span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> myTable
    <span style="color: #0000FF;">SELECT</span> NewID<span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF00FF;">REPLICATE</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'A'</span>, <span style="color: #000;">2000</span><span style="color: #808080;">&#41;</span>;
&nbsp;
    <span style="color: #0000FF;">SET</span> @iteration <span style="color: #808080;">=</span> @iteration <span style="color: #808080;">+</span> <span style="color: #000;">1</span>;
<span style="color: #0000FF;">END</span>
&nbsp;
<span style="color: #008080;">/* Now let's verify that we really did
   make a mess of our clustered index */</span>
<span style="color: #0000FF;">SELECT</span> avg_fragmentation_in_percent
    , page_count
<span style="color: #0000FF;">FROM</span> sys.<span style="color: #202020;">dm_db_index_physical_stats</span> 
<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">DB_ID</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF00FF;">OBJECT_ID</span><span style="color: #808080;">&#40;</span>N<span style="color: #FF0000;">'MyTable'</span><span style="color: #808080;">&#41;</span>, <span style="color: #808080;">NULL</span> , <span style="color: #808080;">NULL</span>, N<span style="color: #FF0000;">'Limited'</span><span style="color: #808080;">&#41;</span> 
<span style="color: #0000FF;">OPTION</span> <span style="color: #808080;">&#40;</span>MaxDop <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>;
&nbsp;
<span style="color: #008080;">/* Results:
&nbsp;
avg_fragmentation_in_percent page_count
---------------------------- --------------------
99.0157480314961             508
&nbsp;
99% fragmented, not too shabby!  Your results 
may vary slightly, based on the guid values
generated by NewID().
*/</span>
&nbsp;
<span style="color: #008080;">/* Now, let's set up replication */</span>
<span style="color: #0000FF;">USE</span> sandbox_publisher;
GO
&nbsp;
<span style="color: #008080;">/* Enable publication */</span>
<span style="color: #0000FF;">EXECUTE</span> <span style="color: #AF0000;">SP_REPLICATIONDBOPTION</span>
      @dbname <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'sandbox_publisher'</span>
    , @optname <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'publish'</span>
    , @<span style="color: #0000FF;">VALUE</span> <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'true'</span>;
GO
&nbsp;
<span style="color: #008080;">/* Create our publication */</span>
<span style="color: #0000FF;">EXECUTE</span> <span style="color: #AF0000;">SP_ADDPUBLICATION</span>
      @publication <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'myTestPublication'</span> 
    , @sync_method <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'concurrent'</span>
    , @description <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'Test Publication'</span>
    , @status <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'active'</span>
    , @independent_agent <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'true'</span>
    , @immediate_sync <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'true'</span>
    , @retention <span style="color: #808080;">=</span> <span style="color: #000;">0</span>
GO
&nbsp;
<span style="color: #008080;">/* Create our snapshot agent */</span>
<span style="color: #0000FF;">EXECUTE</span> <span style="color: #AF0000;">SP_ADDPUBLICATION_SNAPSHOT</span>
      @publication <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'myTestPublication'</span>
    , @frequency_type <span style="color: #808080;">=</span> <span style="color: #000;">1</span>;
&nbsp;
<span style="color: #008080;">/* Add our table as an article */</span>
<span style="color: #0000FF;">EXECUTE</span> <span style="color: #AF0000;">SP_ADDARTICLE</span>
      @publication <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'myTestPublication'</span>
    , @article <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'myTable'</span>
    , @source_owner <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'dbo'</span>
    , @source_object <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'myTable'</span>
    , @type <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'logbased'</span>
    , @destination_table <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'myTable'</span>
    , @destination_owner <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'dbo'</span>
    , @ins_cmd <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'CALL sp_MSins_dbomyTable'</span>
    , @del_cmd <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'CALL sp_MSdel_dbomyTable'</span>
    , @upd_cmd <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'MCALL sp_MSupd_dbomyTable'</span>;
GO
&nbsp;
<span style="color: #008080;">/* Generate an initial snapshot */</span>
<span style="color: #0000FF;">EXECUTE</span> sp_startpublication_snapshot
      @publication <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'myTestPublication'</span>;
&nbsp;
<span style="color: #008080;">/* Create our subscription */</span>
<span style="color: #0000FF;">EXECUTE</span> <span style="color: #AF0000;">SP_ADDSUBSCRIPTION</span> 
      @publication <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'myTestPublication'</span>
    , @subscriber <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'YourServerName'</span>
    , @destination_db <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'sandbox_subscriber'</span>;
&nbsp;
<span style="color: #008080;">/* At this point, basic transactional replication 
   should be configured.  You should now have a 
   copy of myTable in your subscription database. */</span>
&nbsp;
<span style="color: #0000FF;">USE</span> sandbox_subscriber;
GO
&nbsp;
<span style="color: #008080;">/* Let's take a look at fragmentation on the 
   subscription database. */</span>
<span style="color: #0000FF;">SELECT</span> avg_fragmentation_in_percent
    , page_count
<span style="color: #0000FF;">FROM</span> sys.<span style="color: #202020;">dm_db_index_physical_stats</span> 
<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">DB_ID</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF00FF;">OBJECT_ID</span><span style="color: #808080;">&#40;</span>N<span style="color: #FF0000;">'MyTable'</span><span style="color: #808080;">&#41;</span>, <span style="color: #808080;">NULL</span> , <span style="color: #808080;">NULL</span>, N<span style="color: #FF0000;">'Limited'</span><span style="color: #808080;">&#41;</span> 
<span style="color: #0000FF;">OPTION</span> <span style="color: #808080;">&#40;</span>MaxDop <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>;
&nbsp;
<span style="color: #008080;">/* Results:
&nbsp;
avg_fragmentation_in_percent page_count
---------------------------- --------------------
0.29940119760479             334
&nbsp;
Less than 1% fragmented!  Why is this?  During
initialization, a copy of the schema and data
is sent to the subscriber.  The data is sorted
before insertion into the destination table.
*/</span>
&nbsp;
<span style="color: #0000FF;">USE</span> sandbox_publisher;
GO
&nbsp;
<span style="color: #008080;">/* Let's insert another 1000 records and see
   what happens... */</span>
<span style="color: #0000FF;">DECLARE</span> @iteration <span style="color: #0000FF;">INT</span>;
<span style="color: #0000FF;">SET</span> @iteration <span style="color: #808080;">=</span> <span style="color: #000;">0</span>;
&nbsp;
<span style="color: #0000FF;">WHILE</span> @iteration <span style="color: #808080;">&lt;</span> <span style="color: #000;">1000</span>
<span style="color: #0000FF;">BEGIN</span>
    <span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> sandbox_publisher.<span style="color: #202020;">dbo</span>.<span style="color: #202020;">myTable</span>
    <span style="color: #0000FF;">SELECT</span> NewID<span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF00FF;">REPLICATE</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'A'</span>, <span style="color: #000;">2000</span><span style="color: #808080;">&#41;</span>;
&nbsp;
    <span style="color: #0000FF;">SET</span> @iteration <span style="color: #808080;">=</span> @iteration <span style="color: #808080;">+</span> <span style="color: #000;">1</span>;
<span style="color: #0000FF;">END</span>
&nbsp;
<span style="color: #0000FF;">SELECT</span> avg_fragmentation_in_percent
    , page_count
<span style="color: #0000FF;">FROM</span> sys.<span style="color: #202020;">dm_db_index_physical_stats</span> 
<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">DB_ID</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF00FF;">OBJECT_ID</span><span style="color: #808080;">&#40;</span>N<span style="color: #FF0000;">'MyTable'</span><span style="color: #808080;">&#41;</span>, <span style="color: #808080;">NULL</span> , <span style="color: #808080;">NULL</span>, N<span style="color: #FF0000;">'Limited'</span><span style="color: #808080;">&#41;</span> 
<span style="color: #0000FF;">OPTION</span> <span style="color: #808080;">&#40;</span>MaxDop <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>;
&nbsp;
<span style="color: #008080;">/* Results:
&nbsp;
avg_fragmentation_in_percent page_count
---------------------------- --------------------
98.6193293885602             1014
&nbsp;
The publisher is still very fragmented 
(as expected) */</span>
&nbsp;
<span style="color: #0000FF;">USE</span> sandbox_subscriber;
GO
&nbsp;
<span style="color: #0000FF;">SELECT</span> avg_fragmentation_in_percent
    , page_count
<span style="color: #0000FF;">FROM</span> sys.<span style="color: #202020;">dm_db_index_physical_stats</span> 
<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">DB_ID</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF00FF;">OBJECT_ID</span><span style="color: #808080;">&#40;</span>N<span style="color: #FF0000;">'MyTable'</span><span style="color: #808080;">&#41;</span>, <span style="color: #808080;">NULL</span> , <span style="color: #808080;">NULL</span>, N<span style="color: #FF0000;">'Limited'</span><span style="color: #808080;">&#41;</span> 
<span style="color: #0000FF;">OPTION</span> <span style="color: #808080;">&#40;</span>MaxDop <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>;
&nbsp;
<span style="color: #008080;">/* Results:
&nbsp;
avg_fragmentation_in_percent page_count
---------------------------- --------------------
95.4034729315628             979
&nbsp;
But now the subscriber is fragmented too!  This
is because each individual transaction is 
replicated, so out-of-order inserts affect
both the publishing and the subcribing 
databases equally.
*/</span>
&nbsp;
<span style="color: #008080;">/* Finally, let's rebuild our index on the 
   publisher and see what happens */</span>
<span style="color: #0000FF;">USE</span> sandbox_publisher;
GO
&nbsp;
<span style="color: #0000FF;">ALTER</span> <span style="color: #0000FF;">INDEX</span> PK_myTable <span style="color: #0000FF;">ON</span> myTable Rebuild;
&nbsp;
<span style="color: #0000FF;">SELECT</span> avg_fragmentation_in_percent
    , page_count
<span style="color: #0000FF;">FROM</span> sys.<span style="color: #202020;">dm_db_index_physical_stats</span> 
<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">DB_ID</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF00FF;">OBJECT_ID</span><span style="color: #808080;">&#40;</span>N<span style="color: #FF0000;">'MyTable'</span><span style="color: #808080;">&#41;</span>, <span style="color: #808080;">NULL</span> , <span style="color: #808080;">NULL</span>, N<span style="color: #FF0000;">'Limited'</span><span style="color: #808080;">&#41;</span> 
<span style="color: #0000FF;">OPTION</span> <span style="color: #808080;">&#40;</span>MaxDop <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>;
&nbsp;
<span style="color: #008080;">/* Results:
&nbsp;
avg_fragmentation_in_percent page_count
---------------------------- --------------------
0                            667
&nbsp;
0% fragmentation in the publishing table!  
What about our subscribing table?
*/</span>
&nbsp;
<span style="color: #0000FF;">USE</span> sandbox_subscriber;
GO
&nbsp;
<span style="color: #0000FF;">SELECT</span> avg_fragmentation_in_percent
    , page_count
<span style="color: #0000FF;">FROM</span> sys.<span style="color: #202020;">dm_db_index_physical_stats</span> 
<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">DB_ID</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF00FF;">OBJECT_ID</span><span style="color: #808080;">&#40;</span>N<span style="color: #FF0000;">'MyTable'</span><span style="color: #808080;">&#41;</span>, <span style="color: #808080;">NULL</span> , <span style="color: #808080;">NULL</span>, N<span style="color: #FF0000;">'Limited'</span><span style="color: #808080;">&#41;</span> 
<span style="color: #0000FF;">OPTION</span> <span style="color: #808080;">&#40;</span>MaxDop <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>;
&nbsp;
<span style="color: #008080;">/* Results:
&nbsp;
avg_fragmentation_in_percent page_count
---------------------------- --------------------
95.4034729315628             979
&nbsp;
As you can see, the subcribing table was
completely unaffected by the defrag
activities on the publisher.
*/</span></pre></div></div>

<p>So there you have it, proof that defrag operations are not replicated!  Now go defrag your replicated tables.  <img src='http://sqlfool.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Oh, and if you need help defragging your indexes, check out my <a href="http://sqlfool.com/2008/11/updated-index-defrag-script-2005-2008/">index defrag script</a> (2005, 2008).</p>
]]></content:encoded>
			<wfw:commentRss>http://sqlfool.com/2009/01/fragmentation-on-replicated-tables/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Replication Monitor</title>
		<link>http://sqlfool.com/2008/11/replication-monitor/</link>
		<comments>http://sqlfool.com/2008/11/replication-monitor/#comments</comments>
		<pubDate>Tue, 25 Nov 2008 22:05:16 +0000</pubDate>
		<dc:creator>Michelle Ufford</dc:creator>
				<category><![CDATA[SQL Tips]]></category>
		<category><![CDATA[T-SQL Scripts]]></category>
		<category><![CDATA[monitor]]></category>
		<category><![CDATA[replication]]></category>

		<guid isPermaLink="false">http://sqlfool.com/?p=210</guid>
		<description><![CDATA[In my last blog post, I provided a script to view replication latency.  Ian Kirk took the script and ran with it, adding centralized execution and permanent logging. I've tweaked it a little bit further and deployed to production. So far, so good. Here's the latest and greatest for those interested: IF OBJECT_ID&#40;'dbo.dba_replicationMonitor'&#41; IS Null [...]]]></description>
			<content:encoded><![CDATA[<p>In my last blog post, I provided a <a href="http://sqlfool.com/2008/11/checking-replication-latency-with-t-sql/" target="_blank">script to view replication latency</a>.  <a href="http://ilkirk.wordpress.com/" target="_blank">Ian Kirk</a> took the script and ran with it, adding centralized execution and permanent logging.  I've tweaked it a little bit further and deployed to production.  So far, so good.  </p>
<p>Here's the latest and greatest for those interested:</p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">IF</span> <span style="color: #FF00FF;">OBJECT_ID</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'dbo.dba_replicationMonitor'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">IS</span> Null
<span style="color: #0000FF;">BEGIN</span>
    <span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">TABLE</span> dbo.<span style="color: #202020;">dba_replicationMonitor</span>
    <span style="color: #808080;">&#40;</span> 
          monitor_id            <span style="color: #0000FF;">INT</span> <span style="color: #0000FF;">IDENTITY</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1</span>,<span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>   Not Null
        , monitorDate           <span style="color: #0000FF;">SMALLDATETIME</span>       Not Null 
        , publicationName       sysname             Not Null
        , publicationDB         sysname             Not Null
        , iteration             <span style="color: #0000FF;">INT</span>                 Null
        , tracer_id             <span style="color: #0000FF;">INT</span>                 Null
        , distributor_latency   <span style="color: #0000FF;">INT</span>                 Null
        , subscriber            <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1000</span><span style="color: #808080;">&#41;</span>       Null
        , subscriber_db         <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1000</span><span style="color: #808080;">&#41;</span>       Null
        , subscriber_latency    <span style="color: #0000FF;">INT</span>                 Null
        , overall_latency       <span style="color: #0000FF;">INT</span>                 Null 
    <span style="color: #808080;">&#41;</span>;
<span style="color: #0000FF;">END</span>;
&nbsp;
<span style="color: #0000FF;">IF</span> <span style="color: #FF00FF;">OBJECTPROPERTY</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">OBJECT_ID</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'dbo.dba_replicationLatencyMonitor_sp'</span><span style="color: #808080;">&#41;</span>, N<span style="color: #FF0000;">'IsProcedure'</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">=</span> <span style="color: #000;">1</span>
<span style="color: #0000FF;">BEGIN</span>
    <span style="color: #0000FF;">DROP</span> <span style="color: #0000FF;">PROCEDURE</span> dbo.<span style="color: #202020;">dba_replicationLatencyMonitor_sp</span>;
    <span style="color: #0000FF;">PRINT</span> <span style="color: #FF0000;">'Procedure dba_replicationLatencyMonitor_sp dropped'</span>;
<span style="color: #0000FF;">END</span>;
Go
&nbsp;
<span style="color: #0000FF;">SET</span> Quoted_Identifier <span style="color: #0000FF;">ON</span>
Go
<span style="color: #0000FF;">SET</span> ANSI_Nulls <span style="color: #0000FF;">ON</span>
Go
&nbsp;
<span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">PROCEDURE</span> dbo.<span style="color: #202020;">dba_replicationLatencyMonitor_sp</span>
&nbsp;
        <span style="color: #008080;">/* Declare Parameters */</span>
          @publicationToTest    sysname        <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'yourPublicationName'</span>
        , @publicationDB        sysname        <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'yourPublicationDB'</span>
        , @replicationDelay     <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span>    <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'00:00:30'</span>
        , @iterations           <span style="color: #0000FF;">INT</span>            <span style="color: #808080;">=</span> <span style="color: #000;">5</span>
        , @iterationDelay       <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span>    <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'00:00:30'</span>
        , @displayResults       <span style="color: #0000FF;">BIT</span>            <span style="color: #808080;">=</span> <span style="color: #000;">0</span>
        , @deleteTokens         <span style="color: #0000FF;">BIT</span>            <span style="color: #808080;">=</span> <span style="color: #000;">1</span>
<span style="color: #0000FF;">AS</span>
<span style="color: #008080;">/*********************************************************************************
    Name:       dba_replicationLatencyMonitor_sp
&nbsp;
    Author:     Michelle F. Ufford
&nbsp;
    Purpose:    Retrieves the amount of replication latency in seconds
&nbsp;
    Notes:      Default settings will run 1 test every minute for 5 minutes.
&nbsp;
                @publicationToTest = defaults to yourPublicationName publication
&nbsp;
                @publicationDB = the database that is the source for the publication.
				    The tracer procs are found in the publishing DB.
&nbsp;
                @replicationDelay = how long to wait for the token to replicate;
                    probably should not set to anything less than 10 (in seconds)
&nbsp;
                @iterations = how many tokens you want to test
&nbsp;
                @iterationDelay = how long to wait between sending test tokens
                    (in seconds)
&nbsp;
                @displayResults = print results to screen when complete
&nbsp;
                @deleteTokens = whether you want to retain tokens when done
&nbsp;
    Called by:  DBA
&nbsp;
    Date        Initials    Description
    ----------------------------------------------------------------------------
    2008-11-20   MFU        Initial Release
    2008-11-24	 ILK        Tweaked to allow for centralized execution 
                            Replaced temp table with permanent table.
    2008-11-25   MFU        More tweaking, added publication data to 
                            dba_replicationMonitor, fixed NULL latency data,
                            moved dba_replicationMonitor creation out of proc
*********************************************************************************
    Exec dbo.dba_replicationLatencyMonitor_sp
          @publicationToTest    = N'myTestPublication'
        , @publicationDB        = N'sandbox_publisher'
        , @replicationDelay     = N'00:00:05'
        , @iterations           = 1
        , @iterationDelay       = N'00:00:05'
        , @displayResults       = 1
        , @deleteTokens         = 1;
*********************************************************************************/</span>
&nbsp;
<span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span>;
<span style="color: #0000FF;">SET</span> XACT_Abort <span style="color: #0000FF;">ON</span>;
&nbsp;
<span style="color: #0000FF;">BEGIN</span>
&nbsp;
    <span style="color: #008080;">/* Declare Variables */</span>
    <span style="color: #0000FF;">DECLARE</span> @currentIteration   <span style="color: #0000FF;">INT</span>
          , @tokenID            <span style="color: #0000FF;">BIGINT</span>
          , @currentDateTime    <span style="color: #0000FF;">SMALLDATETIME</span>
          , @sqlStatement       <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">200</span><span style="color: #808080;">&#41;</span>
          , @parmDefinition		<span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">500</span><span style="color: #808080;">&#41;</span>;
&nbsp;
    <span style="color: #0000FF;">DECLARE</span> @tokenResults <span style="color: #0000FF;">TABLE</span>
    <span style="color: #808080;">&#40;</span> 
          iteration             <span style="color: #0000FF;">INT</span>             Null
        , tracer_id             <span style="color: #0000FF;">INT</span>             Null
        , distributor_latency   <span style="color: #0000FF;">INT</span>             Null
        , subscriber            <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1000</span><span style="color: #808080;">&#41;</span>   Null
        , subscriber_db         <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1000</span><span style="color: #808080;">&#41;</span>   Null
        , subscriber_latency    <span style="color: #0000FF;">INT</span>             Null
        , overall_latency       <span style="color: #0000FF;">INT</span>             Null 
    <span style="color: #808080;">&#41;</span>;
&nbsp;
    <span style="color: #008080;">/* Initialize our variables */</span>
    <span style="color: #0000FF;">SELECT</span> @currentIteration <span style="color: #808080;">=</span> <span style="color: #000;">0</span>
         , @currentDateTime  <span style="color: #808080;">=</span> <span style="color: #FF00FF;">GETDATE</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>;
&nbsp;
    <span style="color: #0000FF;">WHILE</span> @currentIteration <span style="color: #808080;">&lt;</span> @iterations
    <span style="color: #0000FF;">BEGIN</span>
&nbsp;
		<span style="color: #008080;">/* Prepare the stored procedure execution string */</span>
		<span style="color: #0000FF;">SET</span> @sqlStatement <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'Execute '</span> <span style="color: #808080;">+</span> @publicationDB <span style="color: #808080;">+</span> N<span style="color: #FF0000;">'.sys.sp_postTracerToken '</span> <span style="color: #808080;">+</span> 
							N<span style="color: #FF0000;">'@publication = @VARpublicationToTest , '</span> <span style="color: #808080;">+</span>
							N<span style="color: #FF0000;">'@tracer_token_id = @VARtokenID OutPut;'</span>
&nbsp;
		<span style="color: #008080;">/* Define the parameters used by the sp_ExecuteSQL later */</span>
		<span style="color: #0000FF;">SET</span> @parmDefinition <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'@VARpublicationToTest sysname, '</span> <span style="color: #808080;">+</span>
			N<span style="color: #FF0000;">'@VARtokenID bigint OutPut'</span>;
&nbsp;
        <span style="color: #008080;">/* Insert a new tracer token in the publication database */</span>
        <span style="color: #0000FF;">EXECUTE</span> <span style="color: #AF0000;">SP_EXECUTESQL</span> 
              @sqlStatement
            , @parmDefinition
            , @VARpublicationToTest <span style="color: #808080;">=</span> @publicationToTest
            , @VARtokenID <span style="color: #808080;">=</span> @TokenID <span style="color: #0000FF;">OUTPUT</span>;
&nbsp;
        <span style="color: #008080;">/* Give a few seconds to allow the record to reach the subscriber */</span>
        <span style="color: #0000FF;">WAITFOR</span> Delay @replicationDelay;
&nbsp;
        <span style="color: #008080;">/* Prepare our statement to retrieve tracer token data */</span>
        <span style="color: #0000FF;">SELECT</span> @sqlStatement <span style="color: #808080;">=</span> <span style="color: #FF0000;">'Execute '</span> <span style="color: #808080;">+</span> @publicationDB <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.sys.sp_helpTracerTokenHistory '</span> <span style="color: #808080;">+</span>
                    N<span style="color: #FF0000;">'@publication = @VARpublicationToTest , '</span> <span style="color: #808080;">+</span>
                    N<span style="color: #FF0000;">'@tracer_id = @VARtokenID'</span>
            , @parmDefinition <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'@VARpublicationToTest sysname, '</span> <span style="color: #808080;">+</span>
                    N<span style="color: #FF0000;">'@VARtokenID bigint'</span>;
&nbsp;
        <span style="color: #008080;">/* Store our results for retrieval later */</span>
        <span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> @tokenResults
        <span style="color: #808080;">&#40;</span>
            distributor_latency
          , subscriber
          , subscriber_db
          , subscriber_latency
          , overall_latency
        <span style="color: #808080;">&#41;</span>
        <span style="color: #0000FF;">EXECUTE</span> <span style="color: #AF0000;">SP_EXECUTESQL</span> 
              @sqlStatement
            , @parmDefinition
            , @VARpublicationToTest <span style="color: #808080;">=</span> @publicationToTest
            , @VARtokenID <span style="color: #808080;">=</span> @TokenID;
&nbsp;
        <span style="color: #008080;">/* Assign the iteration and token id to the results for easier investigation */</span>
        <span style="color: #0000FF;">UPDATE</span> @tokenResults
        <span style="color: #0000FF;">SET</span> iteration <span style="color: #808080;">=</span> @currentIteration <span style="color: #808080;">+</span> <span style="color: #000;">1</span>
          , tracer_id <span style="color: #808080;">=</span> @tokenID
        <span style="color: #0000FF;">WHERE</span> iteration <span style="color: #0000FF;">IS</span> Null;
&nbsp;
        <span style="color: #008080;">/* Wait for the specified time period before creating another token */</span>
        <span style="color: #0000FF;">WAITFOR</span> Delay @iterationDelay;
&nbsp;
        <span style="color: #008080;">/* Avoid endless looping... :) */</span>
        <span style="color: #0000FF;">SET</span> @currentIteration <span style="color: #808080;">=</span> @currentIteration <span style="color: #808080;">+</span> <span style="color: #000;">1</span>;
&nbsp;
    <span style="color: #0000FF;">END</span>;
&nbsp;
    <span style="color: #008080;">/* Display our results */</span>
    <span style="color: #0000FF;">IF</span> @displayResults <span style="color: #808080;">=</span> <span style="color: #000;">1</span>
    <span style="color: #0000FF;">BEGIN</span>
        <span style="color: #0000FF;">SELECT</span> 
              iteration
            , tracer_id
            , IsNull<span style="color: #808080;">&#40;</span>distributor_latency, <span style="color: #000;">0</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #FF0000;">'distributor_latency'</span>
            , subscriber
            , subscriber_db
            , IsNull<span style="color: #808080;">&#40;</span>subscriber_latency, <span style="color: #000;">0</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #FF0000;">'subscriber_latency'</span>
            , IsNull<span style="color: #808080;">&#40;</span>overall_latency, 
                IsNull<span style="color: #808080;">&#40;</span>distributor_latency, <span style="color: #000;">0</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> IsNull<span style="color: #808080;">&#40;</span>subscriber_latency, <span style="color: #000;">0</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>
                <span style="color: #0000FF;">AS</span> <span style="color: #FF0000;">'overall_latency'</span>
        <span style="color: #0000FF;">FROM</span> @tokenResults;
    <span style="color: #0000FF;">END</span>;
&nbsp;
    <span style="color: #008080;">/* Store our results */</span>
    <span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> dbo.<span style="color: #202020;">dba_replicationMonitor</span>
    <span style="color: #808080;">&#40;</span>
          monitorDate
        , publicationName
        , publicationDB
        , iteration
        , tracer_id
        , distributor_latency
        , subscriber
        , subscriber_db
        , subscriber_latency
        , overall_latency
    <span style="color: #808080;">&#41;</span>
    <span style="color: #0000FF;">SELECT</span> 
          @currentDateTime
        , @publicationToTest
        , @publicationDB
        , iteration
        , tracer_id
        , IsNull<span style="color: #808080;">&#40;</span>distributor_latency, <span style="color: #000;">0</span><span style="color: #808080;">&#41;</span>
        , subscriber
        , subscriber_db
        , IsNull<span style="color: #808080;">&#40;</span>subscriber_latency, <span style="color: #000;">0</span><span style="color: #808080;">&#41;</span>
        , IsNull<span style="color: #808080;">&#40;</span>overall_latency, 
            IsNull<span style="color: #808080;">&#40;</span>distributor_latency, <span style="color: #000;">0</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> IsNull<span style="color: #808080;">&#40;</span>subscriber_latency, <span style="color: #000;">0</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>
    <span style="color: #0000FF;">FROM</span> @tokenResults;
&nbsp;
    <span style="color: #008080;">/* Delete the tracer tokens if requested */</span>
    <span style="color: #0000FF;">IF</span> @deleteTokens <span style="color: #808080;">=</span> <span style="color: #000;">1</span>
    <span style="color: #0000FF;">BEGIN</span>
&nbsp;
        <span style="color: #0000FF;">SELECT</span> @sqlStatement <span style="color: #808080;">=</span> <span style="color: #FF0000;">'Execute '</span> <span style="color: #808080;">+</span> @publicationDB <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.sys.sp_deleteTracerTokenHistory '</span> <span style="color: #808080;">+</span>
                    N<span style="color: #FF0000;">'@publication = @VARpublicationToTest , '</span> <span style="color: #808080;">+</span>
                    N<span style="color: #FF0000;">'@cutoff_date = @VARcurrentDateTime'</span>
            , @parmDefinition <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'@VARpublicationToTest sysname, '</span> <span style="color: #808080;">+</span>
                    N<span style="color: #FF0000;">'@VARcurrentDateTime datetime'</span>;
&nbsp;
        <span style="color: #0000FF;">EXECUTE</span> <span style="color: #AF0000;">SP_EXECUTESQL</span> 
              @sqlStatement
            , @parmDefinition
            , @VARpublicationToTest <span style="color: #808080;">=</span> @publicationToTest
            , @VARcurrentDateTime <span style="color: #808080;">=</span> @currentDateTime;
&nbsp;
    <span style="color: #0000FF;">END</span>;
&nbsp;
    <span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">OFF</span>;
    <span style="color: #0000FF;">RETURN</span> <span style="color: #000;">0</span>;
<span style="color: #0000FF;">END</span>
Go
&nbsp;
<span style="color: #0000FF;">SET</span> Quoted_Identifier <span style="color: #0000FF;">OFF</span>;
Go
<span style="color: #0000FF;">SET</span> ANSI_Nulls <span style="color: #0000FF;">ON</span>;
Go</pre></div></div>

<p>&nbsp;</p>
<p>Note: All of my stored procedures have standardized error handling that I remove before posting to avoid confusion; you may want to implement your own error handling.</p>
]]></content:encoded>
			<wfw:commentRss>http://sqlfool.com/2008/11/replication-monitor/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Checking Replication Latency with T-SQL</title>
		<link>http://sqlfool.com/2008/11/checking-replication-latency-with-t-sql/</link>
		<comments>http://sqlfool.com/2008/11/checking-replication-latency-with-t-sql/#comments</comments>
		<pubDate>Thu, 20 Nov 2008 20:43:44 +0000</pubDate>
		<dc:creator>Michelle Ufford</dc:creator>
				<category><![CDATA[SQL Tips]]></category>
		<category><![CDATA[T-SQL Scripts]]></category>
		<category><![CDATA[monitor]]></category>
		<category><![CDATA[replication]]></category>

		<guid isPermaLink="false">http://sqlfool.com/?p=204</guid>
		<description><![CDATA[This post may only appeal to small subset of DBA's. This particular script was born of a need to view replication latency in production. I had to investigate whether the replication latency issues we were experiencing in production were occurring on the publisher (us) or the subscriber (them), and address accordingly. "Why just not use [...]]]></description>
			<content:encoded><![CDATA[<p>This post may only appeal to small subset of DBA's.  <img src='http://sqlfool.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>This particular script was born of a need to view replication latency in production.  I had to investigate whether the replication latency issues we were experiencing in production were occurring on the publisher (us) or the subscriber (them), and address accordingly.  "Why just not use Replication Monitor?", you might ask.  Good question!  I would definitely use Replication Monitor if it were available to me; however, I do not have the necessary permissions to the Distributor.  <img src='http://sqlfool.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  </p>
<p>Fortunately, SQL 2005 provides us with some tools to help: <a href="http://msdn.microsoft.com/en-us/library/ms176091.aspx" target="_blank">sp_postTracerToken</a> and <a href="http://msdn.microsoft.com/en-us/library/ms187349(SQL.90).aspx" target="_blank">sp_helpTracerTokenHistory</a>.  This allows us to access the same Tracer Tokens feature that is in Replication Monitor. </p>
<br />
<img src="http://sqlfool.com/blogImages/20081120/ReplicationLatency_Tracer.JPG" alt="Replication Monitor - Tracer Tokens" width="400"/>
<p>&nbsp;</p>
<p>So that's the backstory, and here's the script I came up with.  For those interested, it'd be pretty easy to modify this script to use a permanent table and regularly log replication latency.</p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">PROCEDURE</span> dbo.<span style="color: #202020;">dba_replicationLatencyGet_sp</span>
&nbsp;
        <span style="color: #008080;">/* Declare Parameters */</span>
          @publicationToTest sysname        <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'yourPublicationName'</span>
        , @replicationDelay  <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span>    <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'00:00:30'</span>
        , @iterations        <span style="color: #0000FF;">INT</span>            <span style="color: #808080;">=</span> <span style="color: #000;">5</span>
        , @iterationDelay    <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span>    <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'00:00:30'</span>
        , @deleteTokens      <span style="color: #0000FF;">BIT</span>            <span style="color: #808080;">=</span> <span style="color: #000;">1</span>
        , @deleteTempTable   <span style="color: #0000FF;">BIT</span>            <span style="color: #808080;">=</span> <span style="color: #000;">1</span>
<span style="color: #0000FF;">AS</span>
<span style="color: #008080;">/*********************************************************************************
    Name:       dba_replicationLatencyGet_sp
&nbsp;
    Author:     Michelle F. Ufford
&nbsp;
    Purpose:    Retrieves the amount of replication latency in seconds
&nbsp;
    Notes:      Default settings will run 1 test every minute for 5 minutes.
&nbsp;
                @publicationToTest = change the default to your publication
&nbsp;
                @replicationDelay = how long to wait for the token to replicate;
                    probably should not set to anything less than 10 (in seconds)
&nbsp;
                @iterations = how many tokens you want to test
&nbsp;
                @iterationDelay = how long to wait between sending test tokens
                    (in seconds)
&nbsp;
                @deleteTokens = whether you want to retain tokens when done
&nbsp;
                @deleteTempTable = whether or not to retain the temporary table
                    when done.  Data stored to ##tokenResults; set @deleteTempTable 
                    flag to 0 if you do not want to delete when done.
&nbsp;
    Called by:  DBA
&nbsp;
    Date        Initials    Description
    ----------------------------------------------------------------------------
    2008-11-20   MFU        Initial Release
*********************************************************************************
    Exec dbo.dba_replicationLatencyGet_sp
          @publicationToTest    = N'yourPublicationName'
        , @replicationDelay     = N'00:00:05'
        , @iterations           = 1
        , @iterationDelay       = N'00:00:05'
        , @deleteTokens         = 1
        , @deleteTempTable      = 1;
*********************************************************************************/</span>
&nbsp;
<span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span>;
<span style="color: #0000FF;">SET</span> XACT_Abort <span style="color: #0000FF;">ON</span>;
&nbsp;
<span style="color: #0000FF;">BEGIN</span>
&nbsp;
    <span style="color: #008080;">/* Declare Variables */</span>
    <span style="color: #0000FF;">DECLARE</span> @currentIteration   <span style="color: #0000FF;">INT</span>
          , @tokenID            <span style="color: #0000FF;">BIGINT</span>
          , @currentDateTime    <span style="color: #0000FF;">SMALLDATETIME</span>;
&nbsp;
    <span style="color: #0000FF;">IF</span> <span style="color: #FF00FF;">OBJECT_ID</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'tempdb.dbo.##tokenResults'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">IS</span> Null
    <span style="color: #0000FF;">BEGIN</span>
        <span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">TABLE</span> ##tokenResults
                        <span style="color: #808080;">&#40;</span> iteration           <span style="color: #0000FF;">INT</span>             Null
                        , tracer_id           <span style="color: #0000FF;">INT</span>             Null
                        , distributor_latency <span style="color: #0000FF;">INT</span>             Null
                        , subscriber          <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1000</span><span style="color: #808080;">&#41;</span>   Null
                        , subscriber_db       <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1000</span><span style="color: #808080;">&#41;</span>   Null
                        , subscriber_latency  <span style="color: #0000FF;">INT</span>             Null
                        , overall_latency     <span style="color: #0000FF;">INT</span>             Null <span style="color: #808080;">&#41;</span>;
    <span style="color: #0000FF;">END</span>;
&nbsp;
    <span style="color: #008080;">/* Initialize our variables */</span>
    <span style="color: #0000FF;">SELECT</span> @currentIteration <span style="color: #808080;">=</span> <span style="color: #000;">0</span>
         , @currentDateTime  <span style="color: #808080;">=</span> <span style="color: #FF00FF;">GETDATE</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>;
&nbsp;
    <span style="color: #0000FF;">WHILE</span> @currentIteration <span style="color: #808080;">&lt;</span> @iterations
    <span style="color: #0000FF;">BEGIN</span>
&nbsp;
        <span style="color: #008080;">/* Insert a new tracer token in the publication database */</span>
        <span style="color: #0000FF;">EXECUTE</span> sys.<span style="color: #202020;">sp_postTracerToken</span> 
          @publication <span style="color: #808080;">=</span> @publicationToTest,
          @tracer_token_id <span style="color: #808080;">=</span> @tokenID <span style="color: #0000FF;">OUTPUT</span>;
&nbsp;
        <span style="color: #008080;">/* Give a few seconds to allow the record to reach the subscriber */</span>
        <span style="color: #0000FF;">WAITFOR</span> Delay @replicationDelay;
&nbsp;
        <span style="color: #008080;">/* Store our results in a temp table for retrieval later */</span>
        <span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> ##tokenResults
        <span style="color: #808080;">&#40;</span>
            distributor_latency
          , subscriber
          , subscriber_db
          , subscriber_latency
          , overall_latency
        <span style="color: #808080;">&#41;</span>
        <span style="color: #0000FF;">EXECUTE</span> sys.<span style="color: #202020;">sp_helpTracerTokenHistory</span> @publicationToTest, @tokenID;
&nbsp;
        <span style="color: #008080;">/* Assign the iteration and token id to the results for easier investigation */</span>
        <span style="color: #0000FF;">UPDATE</span> ##tokenResults
        <span style="color: #0000FF;">SET</span> iteration <span style="color: #808080;">=</span> @currentIteration <span style="color: #808080;">+</span> <span style="color: #000;">1</span>
          , tracer_id <span style="color: #808080;">=</span> @tokenID
        <span style="color: #0000FF;">WHERE</span> iteration <span style="color: #0000FF;">IS</span> Null;
&nbsp;
        <span style="color: #008080;">/* Wait for the specified time period before creating another token */</span>
        <span style="color: #0000FF;">WAITFOR</span> Delay @iterationDelay;
&nbsp;
        <span style="color: #008080;">/* Avoid endless looping... :) */</span>
        <span style="color: #0000FF;">SET</span> @currentIteration <span style="color: #808080;">=</span> @currentIteration <span style="color: #808080;">+</span> <span style="color: #000;">1</span>;
&nbsp;
    <span style="color: #0000FF;">END</span>;
&nbsp;
    <span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">*</span> <span style="color: #0000FF;">FROM</span> ##tokenResults;
&nbsp;
    <span style="color: #0000FF;">IF</span> @deleteTempTable <span style="color: #808080;">=</span> <span style="color: #000;">1</span>
    <span style="color: #0000FF;">BEGIN</span>
        <span style="color: #0000FF;">DROP</span> <span style="color: #0000FF;">TABLE</span> ##tokenResults;
    <span style="color: #0000FF;">END</span>;
&nbsp;
    <span style="color: #0000FF;">IF</span> @deleteTokens <span style="color: #808080;">=</span> <span style="color: #000;">1</span>
    <span style="color: #0000FF;">BEGIN</span>
       <span style="color: #0000FF;">EXECUTE</span> sp_deleteTracerTokenHistory @publication <span style="color: #808080;">=</span> @publicationToTest, @cutoff_date <span style="color: #808080;">=</span> @currentDateTime;
    <span style="color: #0000FF;">END</span>;
&nbsp;
    <span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">OFF</span>;
    <span style="color: #0000FF;">RETURN</span> <span style="color: #000;">0</span>;
<span style="color: #0000FF;">END</span>
Go</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://sqlfool.com/2008/11/checking-replication-latency-with-t-sql/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Large Updates on Replicated Tables</title>
		<link>http://sqlfool.com/2008/11/large-updates-on-replicated-tables/</link>
		<comments>http://sqlfool.com/2008/11/large-updates-on-replicated-tables/#comments</comments>
		<pubDate>Sat, 08 Nov 2008 17:42:35 +0000</pubDate>
		<dc:creator>Michelle Ufford</dc:creator>
				<category><![CDATA[SQL Tips]]></category>
		<category><![CDATA[T-SQL Scripts]]></category>
		<category><![CDATA[large]]></category>
		<category><![CDATA[replication]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[TSQL]]></category>
		<category><![CDATA[update]]></category>

		<guid isPermaLink="false">http://sqlfool.com/?p=145</guid>
		<description><![CDATA[Late last night, I executed a 70mm update on a replicated table. This was a somewhat low priority update, so the primary goal (aside from the data change) was to avoid any issues on the publishing and subscribing servers, including replication latency errors. I have performed many large updates in the past, but this was [...]]]></description>
			<content:encoded><![CDATA[<p>Late last night, I executed a 70mm update on a replicated table.  This was a somewhat low priority update, so the primary goal (aside from the data change) was to avoid any issues on the publishing and subscribing servers, including replication latency errors.  I have performed many large updates in the past, but this was the first on a replicated table.  </p>
<p>To minimize impact, one of our system DBA's suggested the use of a replicated stored procedure.  Basically, instead of replicating each of the 70mm updates as a singleton transaction, the replicated stored procedure is called on the subscribing server, which then performs the bulk update locally.  This was my first time using it and it worked beautifully.  </p>
<p>Another of my colleagues, Jeff M., suggested the use of a control table.  Normally, I would just output the last affected ID and update the script manually.  However, this also worked so well that it will be adopted in all future update scripts.</p>
<p>Using the following pseudo-script and a replicated stored procedure, I was able to execute the update on 70mm records in 11.5 hours with *zero* impact on the servers and replication.  I could've probably increased the batch size and reduced the execution time even further, but as I mentioned, this was a low priority update, so there was no need to push it.</p>
<p>This process should work equally well on non-replicated updates; merely replace the Execute statement with the actual update.</p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #008080;">/************ Chunked Update Script with Control Table ************/</span>
&nbsp;
<span style="color: #008080;">/* --------------------- Preparation Script --------------------- */</span>
&nbsp;
<span style="color: #008080;">/* Note: Execute this section in a separate query window */</span>
&nbsp;
<span style="color: #0000FF;">USE</span> yourDatabase;
Go
&nbsp;
<span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span>;
&nbsp;
<span style="color: #008080;">/* Create a control table to facilitate tweaking of parameters */</span>
<span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">TABLE</span> dbo.<span style="color: #202020;">scratch_largeUpdate_control</span>
<span style="color: #808080;">&#40;</span>
      sizeOfBatch       <span style="color: #0000FF;">INT</span>
    , waitForDelay      <span style="color: #0000FF;">CHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">8</span><span style="color: #808080;">&#41;</span>
    , minRecordToUpdate <span style="color: #0000FF;">INT</span> 
    , maxRecordToUpdate <span style="color: #0000FF;">INT</span>
<span style="color: #808080;">&#41;</span>;
&nbsp;
<span style="color: #008080;">/* Create your control data; you only want 1 row in this table */</span>
<span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> dbo.<span style="color: #202020;">scratch_largeUpdate_control</span> 
<span style="color: #808080;">&#40;</span>sizeOfBatch, waitForDelay, minRecordToUpdate, maxRecordToUpdate<span style="color: #808080;">&#41;</span>
<span style="color: #0000FF;">SELECT</span> <span style="color: #000;">10000</span>, <span style="color: #FF0000;">'00:00:05'</span>, <span style="color: #000;">40297132</span>, <span style="color: #000;">107459380</span>;
&nbsp;
<span style="color: #008080;">/* Update Script */</span>
<span style="color: #0000FF;">UPDATE</span> dbo.<span style="color: #202020;">scratch_largeUpdate_control</span>
<span style="color: #0000FF;">SET</span> sizeOfBatch  <span style="color: #808080;">=</span> <span style="color: #000;">100000</span>
  , waitForDelay <span style="color: #808080;">=</span> <span style="color: #FF0000;">'00:00:30'</span>;
&nbsp;
&nbsp;
<span style="color: #008080;">/* ------------------------ Update Script ------------------------ */</span>
<span style="color: #0000FF;">USE</span> yourDatabase;
Go
&nbsp;
<span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span>;
&nbsp;
<span style="color: #0000FF;">DECLARE</span> 
      @batchSize        <span style="color: #0000FF;">INT</span>
    , @minID            <span style="color: #0000FF;">INT</span>
    , @maxID            <span style="color: #0000FF;">INT</span>
    , @procMinID        <span style="color: #0000FF;">INT</span>
    , @procMaxID        <span style="color: #0000FF;">INT</span>
    , @delay            <span style="color: #0000FF;">CHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">8</span><span style="color: #808080;">&#41;</span>
    , @statusMsg        <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1000</span><span style="color: #808080;">&#41;</span>;
&nbsp;
<span style="color: #0000FF;">BEGIN</span> Try
&nbsp;
    <span style="color: #0000FF;">IF</span> <span style="color: #FF00FF;">@@SERVERNAME</span> Not In <span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'PRODSERVER'</span><span style="color: #808080;">&#41;</span>
        <span style="color: #0000FF;">RAISERROR</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'Sorry, this cannot be executed here!'</span>, <span style="color: #000;">16</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>;
&nbsp;
    <span style="color: #0000FF;">IF</span> Not Exists<span style="color: #808080;">&#40;</span>
            <span style="color: #0000FF;">SELECT</span> <span style="color: #FF00FF;">OBJECT_ID</span> 
            <span style="color: #0000FF;">FROM</span> sys.<span style="color: #202020;">objects</span> 
            <span style="color: #0000FF;">WHERE</span> <span style="color: #808080;">&#91;</span>name<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'scratch_largeUpdate_control'</span> 
            And type <span style="color: #808080;">=</span> <span style="color: #FF0000;">'U'</span> <span style="color: #808080;">&#41;</span>
        <span style="color: #0000FF;">RAISERROR</span> <span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'ERROR: Control table does not exist!'</span>, <span style="color: #000;">16</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>
            <span style="color: #0000FF;">WITH</span> NoWait;
    <span style="color: #0000FF;">ELSE</span>
        <span style="color: #0000FF;">SELECT</span> 
              @minID        <span style="color: #808080;">=</span> minRecordToUpdate 
            , @maxID        <span style="color: #808080;">=</span> maxRecordToUpdate 
            , @batchSize    <span style="color: #808080;">=</span> sizeOfBatch
            , @delay        <span style="color: #808080;">=</span> waitForDelay
        <span style="color: #0000FF;">FROM</span> dbo.<span style="color: #202020;">scratch_largeUpdate_control</span> <span style="color: #0000FF;">WITH</span> <span style="color: #808080;">&#40;</span>NoLock<span style="color: #808080;">&#41;</span>;
&nbsp;
    <span style="color: #0000FF;">SET</span> @statusMsg <span style="color: #808080;">=</span> <span style="color: #FF0000;">'Beginning update; batch size of '</span> 
        <span style="color: #808080;">+</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>@batchSize <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">', delay of '</span> 
        <span style="color: #808080;">+</span> @delay <span style="color: #808080;">+</span> <span style="color: #FF0000;">' defined.  Estimate '</span> 
        <span style="color: #808080;">+</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#40;</span>@maxID <span style="color: #808080;">-</span> @minID<span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> @batchSize<span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> 
        <span style="color: #808080;">+</span> <span style="color: #FF0000;">' iterations to be performed.'</span>
&nbsp;
    <span style="color: #0000FF;">RAISERROR</span> <span style="color: #808080;">&#40;</span>@statusMsg, <span style="color: #000;">10</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">WITH</span> NoWait;
&nbsp;
    <span style="color: #0000FF;">WHILE</span> @minID <span style="color: #808080;">&lt;</span> @maxID
    <span style="color: #0000FF;">BEGIN</span>
&nbsp;
        <span style="color: #0000FF;">SELECT</span> @procMinID <span style="color: #808080;">=</span> @minID
            , @procMaxID <span style="color: #808080;">=</span> <span style="color: #808080;">&#40;</span>@minID <span style="color: #808080;">+</span> <span style="color: #808080;">&#40;</span>@batchSize <span style="color: #808080;">-</span> <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>;
&nbsp;
        <span style="color: #008080;">/* Execute actual update code here 
           OR 
           Call a replicated stored procedure, i.e. */</span>
        <span style="color: #0000FF;">EXECUTE</span> dbo.<span style="color: #202020;">myReplicatedUpdateProc</span> 
              @minRecordID <span style="color: #808080;">=</span> @procMinID
            , @maxRecordID <span style="color: #808080;">=</span> @procMaxID;
&nbsp;
        <span style="color: #0000FF;">SET</span> @statusMsg <span style="color: #808080;">=</span> 
            <span style="color: #FF0000;">'Updating records '</span> <span style="color: #808080;">+</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>@minID <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> 
            <span style="color: #808080;">+</span> <span style="color: #FF0000;">' through '</span> <span style="color: #808080;">+</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#40;</span>@minID <span style="color: #808080;">+</span> <span style="color: #808080;">&#40;</span>@batchSize <span style="color: #808080;">-</span> <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> 
            <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'...'</span>;
&nbsp;
        <span style="color: #0000FF;">RAISERROR</span> <span style="color: #808080;">&#40;</span>@statusMsg, <span style="color: #000;">10</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">WITH</span> NoWait;
&nbsp;
        <span style="color: #008080;">/* Update our control table with the last successfully
           updated record ID.  In the event of an error,
           we can start from here. */</span>
        <span style="color: #0000FF;">UPDATE</span> dbo.<span style="color: #202020;">scratch_largeUpdate_control</span> 
        <span style="color: #0000FF;">SET</span> minRecordToUpdate <span style="color: #808080;">=</span> @minID <span style="color: #808080;">+</span> @batchSize;
&nbsp;
        <span style="color: #0000FF;">SELECT</span> @minID <span style="color: #808080;">=</span> @minID <span style="color: #808080;">+</span> @batchSize; 
        <span style="color: #0000FF;">WAITFOR</span> Delay @delay; <span style="color: #008080;">-- breather for the server</span>
&nbsp;
        <span style="color: #008080;">/* Check to see if our control values have changed */</span>
        <span style="color: #0000FF;">IF</span> Not Exists<span style="color: #808080;">&#40;</span>
            <span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">*</span> 
            <span style="color: #0000FF;">FROM</span> dbo.<span style="color: #202020;">scratch_largeUpdate_control</span> <span style="color: #0000FF;">WITH</span> <span style="color: #808080;">&#40;</span>NoLock<span style="color: #808080;">&#41;</span> 
            <span style="color: #0000FF;">WHERE</span> @batchSize <span style="color: #808080;">=</span> sizeOfBatch And @delay <span style="color: #808080;">=</span> waitForDelay<span style="color: #808080;">&#41;</span>
        <span style="color: #0000FF;">BEGIN</span>
&nbsp;
            <span style="color: #008080;">/* There was a change, so grab our new values */</span>
            <span style="color: #0000FF;">SELECT</span> @batchSize <span style="color: #808080;">=</span> sizeOfBatch
                 , @delay <span style="color: #808080;">=</span> waitForDelay
            <span style="color: #0000FF;">FROM</span> dbo.<span style="color: #202020;">scratch_largeUpdate_control</span> <span style="color: #0000FF;">WITH</span> <span style="color: #808080;">&#40;</span>NoLock<span style="color: #808080;">&#41;</span>
&nbsp;
            <span style="color: #008080;">/* Print a status message with the new values */</span>
            <span style="color: #0000FF;">SET</span> @statusMsg <span style="color: #808080;">=</span> <span style="color: #FF0000;">'Parameters changed:  batch size = '</span> 
                <span style="color: #808080;">+</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>@batchSize <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> 
                <span style="color: #808080;">+</span> <span style="color: #FF0000;">', delay = '</span> <span style="color: #808080;">+</span> @delay;
&nbsp;
            <span style="color: #0000FF;">RAISERROR</span> <span style="color: #808080;">&#40;</span>@statusMsg, <span style="color: #000;">10</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">WITH</span> NoWait;
&nbsp;
        <span style="color: #0000FF;">END</span>
    <span style="color: #0000FF;">END</span>
&nbsp;
    <span style="color: #0000FF;">RAISERROR</span> <span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'Success!'</span>, <span style="color: #000;">10</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">WITH</span> NoWait;
&nbsp;
<span style="color: #0000FF;">END</span> Try
<span style="color: #008080;">/* Handle your errors */</span>
<span style="color: #0000FF;">BEGIN</span> Catch
&nbsp;
        <span style="color: #0000FF;">SET</span> @statusMsg <span style="color: #808080;">=</span> <span style="color: #FF0000;">'An error has occurred and the last '</span>
                         <span style="color: #808080;">+</span> <span style="color: #FF0000;">'transaction has been rolled back. '</span>
                         <span style="color: #808080;">+</span> <span style="color: #FF0000;">'Last record successfully updated was '</span>
                         <span style="color: #808080;">+</span> <span style="color: #FF0000;">'record_id = '</span> 
                         <span style="color: #808080;">+</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#40;</span>@minID <span style="color: #808080;">+</span> <span style="color: #808080;">&#40;</span>@batchSize <span style="color: #808080;">-</span> <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> 
                            <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>;
&nbsp;
        <span style="color: #0000FF;">RAISERROR</span> <span style="color: #808080;">&#40;</span>@statusMsg, <span style="color: #000;">16</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">WITH</span> NoWait;
&nbsp;
        <span style="color: #008080;">/* Return the error message */</span>
        <span style="color: #0000FF;">SELECT</span> Error_Number<span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>
            , Error_Procedure<span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>
		    , <span style="color: #FF00FF;">DB_NAME</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>
		    , Error_Line<span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>
		    , Error_Message<span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>
		    , Error_Severity<span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>
		    , Error_State<span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>;
&nbsp;
<span style="color: #0000FF;">END</span> Catch;
&nbsp;
<span style="color: #008080;">/* -------------------------- Clean-Up ----------------------------
Drop Table dbo.scratch_largeUpdate_control;
----------------------------------------------------------------- */</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://sqlfool.com/2008/11/large-updates-on-replicated-tables/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
