<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Warren's DBA Stuff Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/warreny/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/warreny/feed.xml</link>
    <description>Things of interest to SQL Server Database Administrators.</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:34:57 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Record deletes on referenced tables and deadlocks</title>
      <link>https://docs.microsoft.com/archive/blogs/warreny/record-deletes-on-referenced-tables-and-deadlocks</link>
      <pubDate>Sat, 08 Jan 2011 20:46:00 GMT</pubDate>
      <dc:creator><![CDATA[Warren Y]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/warreny/2011/01/08/record-deletes-on-referenced-tables-and-deadlocks/</guid>
      <description><![CDATA[&nbsp;
While troubleshooting some intermittent deadlocking in one of my databases I was surprised...]]></description>
      <content:encoded><![CDATA[<p>&nbsp;</p>
<p><span style="font-size: medium;">While troubleshooting some intermittent deadlocking in one of my databases I was surprised to learn that both commands were deleting single rows from different tables and both lookups were on indexed values. The commands were table scanning and deadlocking on a seemingly unrelated resource in another table.</span></p>
<p><span style="font-size: medium;">After digging in I discovered&nbsp;a chain of triggers and foreign key references with cascade deletes leading back to the deadlocked table, but it still didn't answer why they were deadlocking in the first place and needed a bit more investigation. </span></p>
<p><span style="font-size: medium;">Here's&nbsp;what was happening using an example table pair:</span></p>
<p><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/55/6170.FKRef.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-86-55/6170.FKRef.png" border="0" /></p>
<h2><span style="font-size: large;"><span style="color: #0000ff;">Possible Actions on the Order Table</span></span></h2>
<ol>
<li><span style="font-size: medium;">Insert a record: No problem, just a normal singleton insert</span></li>
<li><span style="font-size: medium;">Update a record: No problem if we are not modifying the value for Id. If we are, then I'd question the underlying database design</span></li>
<li><span style="font-size: medium;">Deleting a record: Here's the problem. Deleting an Order means that SQL needs to check&nbsp;for matching values in&nbsp;OrderItem.OrderID and delete them (cascade delete), or raise an error if it does.</span></li>
</ol>
<p><span style="font-size: medium;">If there's no index on OrderId, then SQL must do a table scan on OrderItem every time&nbsp;we delete a row from Order which takes&nbsp;time and can do deadlock-happy activity like taking range X-X locks . The simple solution to this&nbsp;is creating a nonclustered index on OrderId:</span></p>
<p style="PADDING-LEFT: 30px"><span style="font-size: medium;"><span style="font-size: small;"><span style="color: #0000ff;"><span style="color: #0000ff;">CREATE</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">NONCLUSTERED</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">INDEX</span></span> NCI_OrderITem_OrderID</span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">ON</span></span></span><span style="font-size: small;"> OrderItem<span style="color: #808080;"><span style="color: #808080;">(</span></span>OrderId<span style="color: #808080;"><span style="color: #808080;">)</span></span></span><span style="font-family: Calibri; font-size: small;"><span style="font-family: Calibri; font-size: small;"><span style="color: #008000; font-size: x-small;"><span style="color: #008000;"><span style="font-size: small;"><span lang="EN"> </span></span></span></span></span></span></span></p>
<p><span style="font-size: medium;"><span style="font-family: Calibri; font-size: small;"><span style="font-family: Calibri; font-size: small;"><span style="color: #008000; font-size: x-small;"><span style="color: #008000;"><span style="font-size: small;"><span lang="EN"></span></span></span></span></span></span></span><span style="font-size: medium;">This solves it but raises the question of how many other referencing columns have the same problem. I created a query to look for columns that reference other tables and wasn't the first column in an index. I didn't want the overhead of maintaining a&nbsp;indexes that would never&nbsp;be used, so I&nbsp;restricted it&nbsp;to reference only tables with delete activity. This is what I came up with:</span></p>
<p><span style="font-size: medium;"></span><span style="font-size: large;"><span style="color: #0000ff;">Finding Missing Foreign Key Indexes</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: large;"><span style="color: #0000ff;"></span></span><span style="color: #008000;"><span style="font-size: small;">--Run this from the database you are interested in<br />--Each delete shown in the output represents a table scan on the referencing table</span></span></p>
<p style="padding-left: 30px;"><span style="font-family: Calibri; font-size: small;"><span style="font-family: Calibri; font-size: small;"><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><span style="font-size: small;">WITH</span></span></span><span style="font-size: small;"> ic <span style="color: #0000ff;"><span style="color: #0000ff;">AS </span></span><span style="color: #808080;"><span style="color: #808080;">(</span></span><span style="color: #0000ff;"><span style="color: #0000ff;">SELECT</span></span></span><span style="font-size: small;"> sic<span style="color: #808080;"><span style="color: #808080;">.</span></span><span style="color: #ff00ff;"><span style="color: #ff00ff;">object_id</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span> sic<span style="color: #808080;"><span style="color: #808080;">.</span></span></span><span style="font-size: small;">column_id<br /><span style="color: #0000ff;"><span style="color: #0000ff;">FROM</span></span> <span style="color: #008000;"><span style="color: #008000;">sys</span></span><span style="color: #808080;"><span style="color: #808080;">.</span></span><span style="color: #008000;"><span style="color: #008000;">index_columns</span></span> sic <br /><span style="color: #0000ff;"><span style="color: #0000ff;">WHERE</span></span> key_ordinal<span style="color: #808080;"><span style="color: #808080;">=</span></span></span><span style="font-size: small;">1 <br /></span><span style="font-size: small;"><span style="color: #808080;"><span style="color: #808080;">)<br /></span></span><span style="color: #0000ff;"><span style="color: #0000ff;">SELECT</span></span> <span style="color: #ff00ff;"><span style="color: #ff00ff;">object_name</span></span><span style="color: #808080;"><span style="color: #808080;">(</span></span>fkc<span style="color: #808080;"><span style="color: #808080;">.</span></span>parent_object_id<span style="color: #808080;"><span style="color: #808080;">)</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">'Referencing_table'</span></span></span><span style="font-size: small;"><span style="color: #808080;"><span style="color: #808080;">,<br /></span></span>sc<span style="color: #808080;"><span style="color: #808080;">.</span></span>name <span style="color: #ff0000;"><span style="color: #ff0000;">'Referencing_Column'</span></span></span><span style="font-size: small;"><span style="color: #808080;"><span style="color: #808080;">,<br /></span></span><span style="color: #ff00ff;"><span style="color: #ff00ff;">object_name</span></span><span style="color: #808080;"><span style="color: #808080;">(</span></span>fkc<span style="color: #808080;"><span style="color: #808080;">.</span></span>referenced_object_id<span style="color: #808080;"><span style="color: #808080;">)</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">'Referenced_Table'</span></span></span><span style="font-size: small;"><span style="color: #808080;"><span style="color: #808080;">,<br /></span></span><span style="color: #ff00ff;"><span style="color: #ff00ff;">object_name</span></span><span style="color: #808080;"><span style="color: #808080;">(</span></span>fkc<span style="color: #808080;"><span style="color: #808080;">.</span></span>constraint_object_id<span style="color: #808080;"><span style="color: #808080;">)</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">'FK_Constraint_Name'</span></span></span><span style="font-size: small;"><span style="color: #808080;"><span style="color: #808080;">,<br /></span></span>ios<span style="color: #808080;"><span style="color: #808080;">.</span></span>leaf_delete_count<span style="color: #808080;"><span style="color: #808080;">,</span></span>ios<span style="color: #808080;"><span style="color: #808080;">.</span></span></span><span style="font-size: small;">nonleaf_delete_count<br /><span style="color: #0000ff;"><span style="color: #0000ff;">from</span></span> <span style="color: #008000;"><span style="color: #008000;">sys</span></span><span style="color: #808080;"><span style="color: #808080;">.</span></span><span style="color: #008000;"><span style="color: #008000;">foreign_key_columns</span></span></span><span style="font-size: small;"> fkc<br /><span style="color: #808080;"><span style="color: #808080;">JOIN</span></span> <span style="color: #008000;"><span style="color: #008000;">sys</span></span><span style="color: #808080;"><span style="color: #808080;">.</span></span><span style="color: #008000;"><span style="color: #008000;">dm_db_index_operational_stats</span></span><span style="color: #0000ff;"><span style="color: #0000ff;"> </span></span><span style="color: #808080;"><span style="color: #808080;">(</span></span><span style="color: #ff00ff;"><span style="color: #ff00ff;">db_id</span></span><span style="color: #808080;"><span style="color: #808080;">(),</span></span> <span style="color: #808080;"><span style="color: #808080;">NULL,</span></span> <span style="color: #808080;"><span style="color: #808080;">NULL,</span></span> <span style="color: #808080;"><span style="color: #808080;">NULL)</span></span> ios <span style="color: #0000ff;"><span style="color: #0000ff;">ON </span></span><span style="color: #808080;"><span style="color: #808080;">(</span></span>fkc<span style="color: #808080;"><span style="color: #808080;">.</span></span>referenced_object_id <span style="color: #808080;"><span style="color: #808080;">=</span></span> ios<span style="color: #808080;"><span style="color: #808080;">.</span></span></span><span style="font-size: small;"><span style="color: #ff00ff;"><span style="color: #ff00ff;">object_id</span></span><span style="color: #808080;"><span style="color: #808080;">)<br />LEFT</span></span> <span style="color: #808080;"><span style="color: #808080;">JOIN</span></span> ic <span style="color: #0000ff;"><span style="color: #0000ff;">ON </span></span><span style="color: #808080;"><span style="color: #808080;">(</span></span>fkc<span style="color: #808080;"><span style="color: #808080;">.</span></span>parent_object_id <span style="color: #808080;"><span style="color: #808080;">=</span></span> ic<span style="color: #808080;"><span style="color: #808080;">.</span></span><span style="color: #ff00ff;"><span style="color: #ff00ff;">object_id</span></span> <span style="color: #808080;"><span style="color: #808080;">AND</span></span> fkc<span style="color: #808080;"><span style="color: #808080;">.</span></span>parent_column_id <span style="color: #808080;"><span style="color: #808080;">=</span></span> ic<span style="color: #808080;"><span style="color: #808080;">.</span></span>column_id</span><span style="font-size: small;"><span style="color: #808080;"><span style="color: #808080;">)<br />JOIN</span></span> <span style="color: #008000;"><span style="color: #008000;">sys</span></span><span style="color: #808080;"><span style="color: #808080;">.</span></span><span style="color: #008000;"><span style="color: #008000;">columns</span></span> sc <span style="color: #0000ff;"><span style="color: #0000ff;">ON </span></span><span style="color: #808080;"><span style="color: #808080;">(</span></span>fkc<span style="color: #808080;"><span style="color: #808080;">.</span></span>parent_object_id <span style="color: #808080;"><span style="color: #808080;">=</span></span> sc<span style="color: #808080;"><span style="color: #808080;">.</span></span><span style="color: #ff00ff;"><span style="color: #ff00ff;">object_id</span></span> <span style="color: #808080;"><span style="color: #808080;">AND</span></span> fkc<span style="color: #808080;"><span style="color: #808080;">.</span></span>parent_column_id <span style="color: #808080;"><span style="color: #808080;">=</span></span> sc<span style="color: #808080;"><span style="color: #808080;">.</span></span>column_id</span><span style="font-size: small;"><span style="color: #808080;"><span style="color: #808080;">) <br /></span></span><span style="color: #0000ff;"><span style="color: #0000ff;">where</span></span> 1<span style="color: #808080;"><span style="color: #808080;">=</span></span></span><span style="font-size: small;">1 <br /><span style="color: #808080;"><span style="color: #808080;">AND</span></span> ic<span style="color: #808080;"><span style="color: #808080;">.</span></span><span style="color: #ff00ff;"><span style="color: #ff00ff;">object_id</span></span> <span style="color: #808080;"><span style="color: #808080;">IS</span></span> </span><span style="font-size: small;"><span style="color: #808080;"><span style="color: #808080;">NULL<br />AND</span></span> ios<span style="color: #808080;"><span style="color: #808080;">.</span></span>index_id <span style="color: #808080;"><span style="color: #808080;">in</span></span><span style="color: #0000ff;"><span style="color: #0000ff;"> </span></span><span style="color: #808080;"><span style="color: #808080;">(</span></span>0<span style="color: #808080;"><span style="color: #808080;">,</span></span>1</span><span style="font-size: small;"><span style="color: #808080;"><span style="color: #808080;">)<br />AND</span></span><span style="color: #0000ff;"><span style="color: #0000ff;"> </span></span><span style="color: #808080;"><span style="color: #808080;">(</span></span>ios<span style="color: #808080;"><span style="color: #808080;">.</span></span>leaf_delete_count <span style="color: #808080;"><span style="color: #808080;">&gt;</span></span> 0 <span style="color: #808080;"><span style="color: #808080;">OR</span></span> ios<span style="color: #808080;"><span style="color: #808080;">.</span></span>nonleaf_delete_count <span style="color: #808080;"><span style="color: #808080;">&gt;</span></span> 0</span><span style="color: #808080; font-size: x-small;"><span style="color: #808080;"><span style="font-size: small;">)</span></span></span></span></span></p>
<h2><span style="font-size: large;"><span style="color: #0000ff;">What the query returns</span></span></h2>
<p><span style="font-size: large;"><span style="color: #0000ff;"><span style="font-size: medium;"><span style="color: #333333;">We get a result set similar to the following (*<span style="font-size: small;">two columns omitted)</span>:</span></span></span></span></p>
<p><span style="font-size: large;"><span style="color: #0000ff;"><span style="font-size: medium;"><span style="color: #333333;"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/55/5282.FKTable.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-86-55/5282.FKTable.png" border="0" /></span></span></span></span></p>
<h2><span style="font-size: large;"><span style="color: #0000ff;">Conclusion</span></span></h2>
<p><span style="font-size: medium;">Over 5 million deletes&nbsp;from order&nbsp;and with&nbsp;each&nbsp;causing a table scan on OrderItem, and 665000 deletes from customers each&nbsp;causing a table scan on Profile regardless of whether the delete even cascaded. </span></p>
<p><span style="font-size: medium;">The 74 deletes from Catalog cause the same problem, but&nbsp;here we get into the question of whether the overhead of maintaining an additional 5 indexes&nbsp;would be&nbsp;worth the benefit. For Profile and OrderItem it was a no-brainer to add nonclustered indexes to the CustomerId and ItemId columns.</span></p>
<p><span style="font-size: medium;">&nbsp;</span></p>]]></content:encoded>
    </item>
    <item>
      <title>SQL Server Replication: Synchronize From Backup</title>
      <link>https://docs.microsoft.com/archive/blogs/warreny/sql-server-replication-synchronize-from-backup</link>
      <pubDate>Mon, 03 Jan 2011 13:20:00 GMT</pubDate>
      <dc:creator><![CDATA[Warren Y]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/warreny/2011/01/03/sql-server-replication-synchronize-from-backup/</guid>
      <description><![CDATA[Synchronize from Backup is the first of the "No Sync" scenarios and is typically the next scenario...]]></description>
      <content:encoded><![CDATA[<p><span style="font-size: medium;">Synchronize from Backup is the first of the "No Sync" scenarios and is typically the next scenario people look at when automatic synchronization becomes impractical</span></p>
<h1><span style="color: #0000ff;"><span style="font-size: x-large;">Synchronize From Backup</span></span></h1>
<p><span style="font-size: medium;">This method cannot be done from the GUI and must be done through script. The basic process involves making a backup of the publisher database, restoring it to the subscriber, then create the subscription specifying the backup file. SQL will read the Log Sequence Number (lsn) from the header and apply all transactions that have occurred since that point.</span></p>
<h2><span style="font-size: large;"></span></h2>
<h2><span style="color: #0000ff;"><span style="font-size: large;"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/55/6428.SyncMitBackup.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-86-55/6428.SyncMitBackup.png" border="0" style="FLOAT: left" /></span></span></h2>
<h2><span style="color: #0000ff;"><span style="font-size: large;">Advantages</span></span></h2>
<ul>
<li><span style="font-size: medium;">Much faster than automatic for large databases</span></li>
<li><span style="font-size: medium;">Much faster than automatic for long distances</span></li>
<li><span style="font-size: medium;">No blocking on the publisher database</span></li>
</ul>
<h2><span style="color: #0000ff;"><span style="font-size: large;">Disadvantages</span></span></h2>
<ul>
<li><span style="font-size: medium;">Restoring the database overwrites the current database on the subscriber</span></li>
<li><span style="font-size: medium;">Must manually correct any incompatible features on the subscriber</span></li>
<li><span style="font-size: medium;">Database permissions are replaces with the publisher permissions</span></li>
<li><span style="font-size: medium;">Orphaned users</span></li>
</ul>
<h2><span style="color: #0000ff;"><span style="font-size: large;">Best Used When</span></span></h2>
<ul>
<li><span style="font-size: medium;">Database is very large</span></li>
<li><span style="font-size: medium;">Publisher and subscriber are geographically distant over a WAN</span></li>
<li><span style="font-size: medium;">Most or all of the database is published</span></li>
<li><span style="font-size: medium;">Publisher schema works as a subscriber schema with little modification</span></li>
</ul>
<h2><span style="color: #0000ff;"><span style="font-size: large;">Notes</span></span></h2>
<ol>
<li><span style="font-size: medium;"><span style="text-decoration: underline;">Must use a publisher backup</span>: One of the caveats to sync with backup is that the backup must be from the publisher database. You cannot take a backup from another subscriber and sync with it, though there are some tricks to make it work.</span></li>
<li><span style="font-size: medium;"><span style="text-decoration: underline;">Database overwritten</span>: Since the entire database is overwritten, all objects in it are replaced with whatever was on the publisher database. The usual fix for this is to script everything on the subscriber that is needed and replace them after restoring the backup. Some items include:</span> <ol>
<li><span style="font-size: medium;">Permissions</span></li>
<li><span style="font-size: medium;">Roles</span></li>
<li><span style="font-size: medium;">Users</span></li>
<li><span style="font-size: medium;">Objects (functions, stored procedures, etc)</span></li>
<li><span style="font-size: medium;">Indexes</span></li>
</ol></li>
<li><span style="font-size: medium;"><span style="text-decoration: underline;">Orphaned SQL Users</span>: Any SQL logins created with a different SID won't map to user in the database when restored, and you'll see errors like this:</span>
<p><span style="color: #ff0000;"><span style="font-size: small;">Error: 18456, Severity: 14, State: 38. Login failed for user 'foo'.<br />Reason: Failed to open the explicitly specified database. [CLIENT: x.x.x.x]&nbsp;</span></span></p>
<p><span style="color: #ff0000;"></span><span style="font-size: medium;">The ways to fix these is to recreate the login using the SID from the publisher, or remap the user to the login using either sp_change_users_login or ALTER USER</span></p>
</li>
<li><span style="font-size: medium;"><span style="text-decoration: underline;">Not For Replication Option</span>: As a general rule all objects in the publisher database that can have the 'NOT FOR REPLICATION' option should be created with it. What the option does is ignore the specific feature if a replication agent is doing the work. There are four of these:</span> <ol>
<li><span style="font-size: medium;">Foreign Keys: The constraint was already checked on the publisher and does not need to be rechecked on an identical subscriber.</span></li>
<li><span style="font-size: medium;">Check Constraints: Same reason as foreign key</span></li>
<li><span style="font-size: medium;">Identity Columns: The publisher will insert the identity value directly into the table to maintain the same values between both servers, so the replication agent would encounter an insert error if not set. One side effect of this is that the identity value will not update, so if inserts need to be made on the subscriber (peer-to-peer replication, for example) then update the identity seed using a range that won't conflict with the publisher using DBCC CHECKIDENT (RESEED)</span></li>
<li><span style="font-size: medium;">Triggers: Generally it's better to publish the base tables that a trigger modifies instead of letting it fire on the subscriber. Replicating both the trigger with 'for replication' and the base table will cause a conflict.</span></li>
</ol></li>
<li><span style="font-size: medium;"><span style="text-decoration: underline;">Long Copy / Restore Time</span>: With extremely large databases it can take several hours to copy it across the network and restore. The way to work around this problem is to do the initial restore with the NORECOVERY option, then create and apply a differential backup to catch up on recent transactions. </span></li>
<li><span style="font-size: medium;"><span style="text-decoration: underline;">Required transactions missing</span>: When you try to create the subscription you get the message below. </span></li>
</ol>
<p><span style="color: #ff0000;"><span style="font-size: small;">Msg 21397 <br />The transactions required for synchronizing the nosync subscription created from the specified backup are unavailable at the Distributor. Retry the operation again with a more up-to-date log, differential, or full database backup.</span></span></p>
<p><span style="font-size: medium;">This is usually caused by not having a minimum retention time set on the distributor and the distribution cleanup agent removes the transactions since they have already been distributed to all <i>existing</i> subscribers. The solution is to disable the distribution cleanup agent before taking the backup.&nbsp; </span></p>
<p><span style="font-size: medium;">If you already see the message it's too late and the best way out is to restore the database again with NORECOVERY, then disable the distribution cleanup agent, and finally backup a differential and restore it. Use the differential to synchronize.</span></p>
<p>&nbsp;<span style="color: #008000; font-size: x-small;"><span style="color: #008000; font-size: x-small;"><br /><span style="font-size: small;">/*===============================================================================================*/<br />/*Add Transactional snapshot subscription */<br />/*Restore and synchronize using backup */<br />/*SQL 2005 or SQL 2008 */<br />/* */<br />/*Use Ctrl-Shift-&lt;M&gt; to replace template parameters */<br />&nbsp;<br />/*=============================================================================================================================*/<br />--1. Run on Distributor: &lt;Distributor, varchar, DistServer&gt; <br />--Stop distribution cleanup agent<br />--<br />--You'll see an error if the job isn't running, it's normal</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">USE</span></span></span><span style="font-size: small;"> <span style="color: #808080;"><span style="color: #808080;">&lt;</span></span>Distribution_DB<span style="color: #808080;"><span style="color: #808080;">,</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">varchar</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span> distribution<span style="color: #808080;"><span style="color: #808080;">&gt;</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">GO<br />EXEC</span></span></span><span style="font-size: small;"> msdb<span style="color: #808080;"><span style="color: #808080;">..</span></span><span style="color: #800000;"><span style="color: #800000;">sp_update_job</span></span><span style="color: #0000ff;"><span style="color: #0000ff;"> </span></span>@job_name <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">'Distribution clean up: &lt;Distribution_DB, varchar, distribution&gt;'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span> @enabled <span style="color: #808080;"><span style="color: #808080;">=</span></span> 0<span style="color: #808080;"><span style="color: #808080;">;</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">EXEC</span></span></span><span style="font-size: small;"> msdb<span style="color: #808080;"><span style="color: #808080;">..</span></span><span style="color: #800000;"><span style="color: #800000;">sp_stop_job</span></span><span style="color: #0000ff;"><span style="color: #0000ff;"> </span></span>@job_name <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">'Distribution clean up: &lt;Distribution_DB, varchar, distribution&gt;'</span></span></span><span style="color: #008000; font-size: x-small;"><span style="color: #008000; font-size: x-small;"><br /><span style="font-size: small;"></span></span></span></p>
<p>
<p><span style="color: #008000; font-size: x-small;"><span style="color: #008000; font-size: x-small;"><span style="font-size: small;">
<p><br />/*===============================================================================================*/<br />--2. Run on Publisher: &lt;Publisher, varchar, PubServer&gt;<br />--In the publisher DB: &lt;PublisherDB, varchar, PubDB&gt;<br />--<br />--Steps 1 and 2 manually delete the subscription from the publisher and subscriber.<br />--If you drop the subscription through the GUI, and select the option to connect to <br />--the subscriber and delete the record, you can skip steps 1 and 2.<br />--This way you don't have to bother with opening the new query window for step 2</p>
<span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">USE</span></span></span><span style="font-size: small;"> <span style="color: #808080;"><span style="color: #808080;">&lt;</span></span>PublisherDB<span style="color: #808080;"><span style="color: #808080;">,</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">varchar</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span> PubDB<span style="color: #808080;"><span style="color: #808080;">&gt;</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">GO<br /></span></span></span><span style="color: #008000; font-size: x-small;"><span style="color: #008000; font-size: x-small;"><br /><span style="font-size: small;">--Need to set option: 'allow Initialization from backup' on the Publication</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">EXEC</span></span></span><span style="font-size: small;"> <span style="color: #800000;"><span style="color: #800000;">sp_changepublication</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /></span></span><span style="font-size: small;">@publication <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'&lt;Publication, varchar, PubName&gt;'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@property <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'allow_initialize_from_backup'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: x-small;"><br /><span style="font-size: small;">@value </span></span><span style="font-size: small;"><span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">'true'</span></span></span><span style="color: #008000; font-size: x-small;"><span style="color: #008000; font-size: x-small;"><br /><span style="font-size: small;">--Drop the existing subscription if present<br />--</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">IF</span></span></span><span style="font-size: small;"> <span style="color: #808080;"><span style="color: #808080;">EXISTS</span></span><span style="color: #0000ff;"><span style="color: #0000ff;"> </span></span><span style="color: #808080;"><span style="color: #808080;">(</span></span></span><span style="font-size: x-small;"><br /></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff;"><span style="font-size: small;">SELECT</span></span></span><span style="font-size: small;"> 1 <br /><span style="color: #0000ff;"><span style="color: #0000ff;">FROM</span></span></span><span style="font-size: small;"> syspublications sp<br /><span style="color: #808080;"><span style="color: #808080;">JOIN</span></span> sysarticles sa <span style="color: #0000ff;"><span style="color: #0000ff;">ON </span></span><span style="color: #808080;"><span style="color: #808080;">(</span></span>sp<span style="color: #808080;"><span style="color: #808080;">.</span></span>pubid <span style="color: #808080;"><span style="color: #808080;">=</span></span> sa<span style="color: #808080;"><span style="color: #808080;">.</span></span>pubid<span style="color: #808080;"><span style="color: #808080;">)</span></span></span><span style="font-size: x-small;"><br /></span><span style="font-size: small;"><span style="color: #808080;"><span style="color: #808080;">JOIN</span></span> syssubscriptions ss <span style="color: #0000ff;"><span style="color: #0000ff;">ON </span></span><span style="color: #808080;"><span style="color: #808080;">(</span></span>sa<span style="color: #808080;"><span style="color: #808080;">.</span></span>artid <span style="color: #808080;"><span style="color: #808080;">=</span></span> ss<span style="color: #808080;"><span style="color: #808080;">.</span></span>artid<span style="color: #808080;"><span style="color: #808080;">)</span></span></span><span style="font-size: x-small;"><br /></span><span style="font-size: small;"><span style="color: #0000ff;"><span style="color: #0000ff;">WHERE</span></span> sp<span style="color: #808080;"><span style="color: #808080;">.</span></span>Name <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'&lt;Publication, varchar, PubName&gt;'</span></span></span><span style="font-size: x-small;"><br /></span><span style="font-size: small;"><span style="color: #808080;"><span style="color: #808080;">AND</span></span> ss<span style="color: #808080;"><span style="color: #808080;">.</span></span>srvname <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'&lt;NewSubscriber, varchar, NewSubServer&gt;'</span></span></span><span style="font-size: x-small;"><br /></span><span style="font-size: small;"><span style="color: #808080;"><span style="color: #808080;">AND</span></span> ss<span style="color: #808080;"><span style="color: #808080;">.</span></span>dest_db <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'&lt;NewSubDB, varchar, PubDB&gt;'</span></span> </span><span style="color: #808080; font-size: x-small;"><span style="color: #808080; font-size: x-small;"><br /><span style="font-size: small;">)</span></span></span><span style="font-size: x-small;"><br /></span><span style="font-size: small;"><span style="color: #0000ff;"><span style="color: #0000ff;">EXEC</span></span> <span style="color: #800000;"><span style="color: #800000;">sp_dropsubscription</span></span></span><span style="font-size: small;"><span style="color: #0000ff;"><span style="color: #0000ff;"> <br /></span></span>@publication <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'&lt;Publication, varchar, PubName&gt;'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@subscriber <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'&lt;NewSubscriber, varchar, NewSubServer&gt;'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@destination_db <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'&lt;NewSubDB, varchar, PubDB&gt;'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: x-small;"><br /><span style="font-size: small;">@article</span></span><span style="font-size: small;"><span style="color: #808080;"><span style="color: #808080;">=</span></span><span style="color: #ff0000;"><span style="color: #ff0000;">'all'</span></span></span><span style="color: #008000; font-size: x-small;"><span style="color: #008000; font-size: x-small;"><br /><span style="font-size: small;">--Note: Full backup only in this script.<br />--If you want to do a diff, I recommend doing your full backup<br />--and restore w/ NORECOVERY before running this script. <br />--then add , WITH DIFFERENTIAL to the below command.<br />--When the full is mostly restored on the subscriber, use this script to finish<br />--</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">BACKUP</span></span></span><span style="font-size: small;"> <span style="color: #0000ff;"><span style="color: #0000ff;">DATABASE</span></span> <span style="color: #808080;"><span style="color: #808080;">&lt;</span></span>PublisherDB<span style="color: #808080;"><span style="color: #808080;">,</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">varchar</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span> PubDB<span style="color: #808080;"><span style="color: #808080;">&gt;</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">TO</span></span></span><span style="font-size: small;"> <span style="color: #0000ff;"><span style="color: #0000ff;">DISK</span></span> <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">'&lt;Publisher_Backup_Path, varchar, E:\MSSQL\Backup&gt;\&lt;PublisherDB, varchar, PubDB&gt;.BAK'</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">WITH</span></span></span><span style="font-size: small;"> <span style="color: #008000;"><span style="color: #008000;">STATS</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">INIT</span></span></span><span style="color: #008000; font-size: x-small;"><span style="color: #008000; font-size: x-small;"><br /><span style="font-size: small;"><br />/*=============================================================================================================================*/<br />--3. Run on New Subscriber: &lt;NewSubscriber, varchar, NewSubServer&gt;<br />--Copy the file to the new server<br />--Run this from a command prompt, and change the copy command depending on your OS version<br />--Lots of options here, especially if you decided to stripe backups, etc.<br />--<br />--***Run this from a command prompt. Change the copy command depending on your OS version and what utilities you have available</span></span></span><span style="font-size: x-small;"><br /><span style="font-size: small;">ROBOCOPY "&lt;Publisher_Remote_Backup_Path, varchar, </span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff;"><span style="font-size: small;">&lt;\\PubServer\E$\MSSQL\Backup&gt;</span></span></span><span style="font-size: small;">&gt;" "&lt;NewSubscriber_Backup_Path, varchar, E:\MSSQL\Backup&gt;" "&lt;PublisherDB, varchar, PubDB&gt;.BAK"<br /></span><span style="color: #008000; font-size: x-small;"><span style="color: #008000; font-size: x-small;"><br /><span style="font-size: small;">--4. Run on New Subscriber: &lt;NewSubscriber, varchar, NewSubServer&gt;<br />--Restore the database</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">USE</span></span></span><span style="font-size: small;"> </span><span style="font-size: small;"><span style="color: #0000ff;"><span style="color: #0000ff;">master<br />GO<br />IF</span></span> <span style="color: #808080;"><span style="color: #808080;">EXISTS</span></span><span style="color: #0000ff;"><span style="color: #0000ff;"> </span></span><span style="color: #808080;"><span style="color: #808080;">(</span></span><span style="color: #0000ff;"><span style="color: #0000ff;">SELECT</span></span> 1 <span style="color: #0000ff;"><span style="color: #0000ff;">FROM</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">master</span></span><span style="color: #808080;"><span style="color: #808080;">.</span></span><span style="color: #008000;"><span style="color: #008000;">sys</span></span><span style="color: #808080;"><span style="color: #808080;">.</span></span><span style="color: #008000;"><span style="color: #008000;">databases</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">WHERE</span></span> name <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">'&lt;NewSubDB, varchar, PubDB&gt;'</span></span><span style="color: #808080;"><span style="color: #808080;">)</span></span></span><span style="font-size: x-small;"><br /></span><span style="font-size: small;"><span style="color: #0000ff;"><span style="color: #0000ff;">ALTER</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">DATABASE</span></span> <span style="color: #808080;"><span style="color: #808080;">&lt;</span></span>NewSubDB<span style="color: #808080;"><span style="color: #808080;">,</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">varchar</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span> PubDB<span style="color: #808080;"><span style="color: #808080;">&gt;</span></span></span><span style="font-size: x-small;"><br /></span><span style="font-size: small;"><span style="color: #0000ff;"><span style="color: #0000ff;">SET</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">OFFLINE</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">WITH</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">ROLLBACK</span></span> </span><span style="font-size: small;"><span style="color: #0000ff;"><span style="color: #0000ff;">IMMEDIATE<br />GO<br />RESTORE</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">DATABASE</span></span> <span style="color: #808080;"><span style="color: #808080;">&lt;</span></span>NewSubDB<span style="color: #808080;"><span style="color: #808080;">,</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">varchar</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span> PubDB<span style="color: #808080;"><span style="color: #808080;">&gt;</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">FROM</span></span></span><span style="font-size: small;"> <span style="color: #0000ff;"><span style="color: #0000ff;">DISK</span></span> <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">'&lt;NewSubscriber_Backup_Path, varchar, E:\MSSQL\Backup&gt;\&lt;PublisherDB, varchar, PubDB&gt;.BAK'</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">WITH</span></span></span><span style="font-size: small;"> <span style="color: #008000;"><span style="color: #008000;">STATS</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span> <span style="color: #ff00ff;"><span style="color: #ff00ff;">REPLACE</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">GO</span></span></span><span style="color: #008000; font-size: x-small;"><span style="color: #008000; font-size: x-small;"><br /><span style="font-size: small;"><br />/*============================================================================*/<br />--5. Run on Publisher: &lt;Publisher, varchar, PubServer&gt;<br />--In the publisher DB: &lt;PublisherDB, varchar, PubDB&gt;<br />--Initialize the subscription with a backup file.<br />--The other thread from the subscriber should still be running to update the lsn<br />--As soon as the subscription is created</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">USE</span></span></span><span style="font-size: small;"> <span style="color: #808080;"><span style="color: #808080;">&lt;</span></span>PublisherDB<span style="color: #808080;"><span style="color: #808080;">,</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">varchar</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span> PubDB<span style="color: #808080;"><span style="color: #808080;">&gt;</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">GO<br />exec</span></span></span><span style="font-size: small;"> <span style="color: #800000;"><span style="color: #800000;">sp_addsubscription</span></span></span><span style="font-size: small;"><span style="color: #0000ff;"><span style="color: #0000ff;"> <br /></span></span>@publication <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'&lt;Publication, varchar, PubName&gt;'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@subscriber <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'&lt;NewSubscriber, varchar, NewSubServer&gt;'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@destination_db <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'&lt;NewSubDB, varchar, PubDB&gt;'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@subscription_type <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'Push'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@sync_type <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'initialize with backup'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@backupDeviceType <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'Disk'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@backupDeviceName <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'&lt;NewSubscriber_Backup_Path, varchar, E:\MSSQL\Backup&gt;\&lt;PublisherDB, varchar, PubDB&gt;.BAK'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@update_mode <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'read only'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@subscriber_type <span style="color: #808080;"><span style="color: #808080;">=</span></span> 0</span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">exec</span></span></span><span style="font-size: small;"> <span style="color: #800000;"><span style="color: #800000;">sp_addpushsubscription_agent</span></span></span><span style="font-size: small;"><span style="color: #0000ff;"><span style="color: #0000ff;"> <br /></span></span>@publication <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'&lt;Publication, varchar, PubName&gt;'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@subscriber <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'&lt;NewSubscriber, varchar, NewSubServer&gt;'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@subscriber_db <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">N'&lt;NewSubDB, varchar, PubDB&gt;'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@job_login <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #808080;"><span style="color: #808080;">null,</span></span></span><span style="font-size: small;"> <br />@job_password <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #808080;"><span style="color: #808080;">null,</span></span></span><span style="font-size: small;"> <br />@subscriber_security_mode <span style="color: #808080;"><span style="color: #808080;">=</span></span> 1<span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@frequency_type <span style="color: #808080;"><span style="color: #808080;">=</span></span> 64<span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@frequency_interval <span style="color: #808080;"><span style="color: #808080;">=</span></span> 1<span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@frequency_relative_interval <span style="color: #808080;"><span style="color: #808080;">=</span></span> 1<span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@frequency_recurrence_factor <span style="color: #808080;"><span style="color: #808080;">=</span></span> 0<span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@frequency_subday <span style="color: #808080;"><span style="color: #808080;">=</span></span> 4<span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@frequency_subday_interval <span style="color: #808080;"><span style="color: #808080;">=</span></span> 5<span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@active_start_time_of_day <span style="color: #808080;"><span style="color: #808080;">=</span></span> 0<span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@active_end_time_of_day <span style="color: #808080;"><span style="color: #808080;">=</span></span> 235959<span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@active_start_date <span style="color: #808080;"><span style="color: #808080;">=</span></span> 0<span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@active_end_date <span style="color: #808080;"><span style="color: #808080;">=</span></span> 0<span style="color: #808080;"><span style="color: #808080;">,</span></span></span><span style="font-size: small;"> <br />@dts_package_location <span style="color: #808080;"><span style="color: #808080;">=</span></span> </span><span style="color: #ff0000; font-size: x-small;"><span style="color: #ff0000;"><span style="font-size: small;">N'Distributor'<br /></span></span></span><span style="color: #008000; font-size: x-small;"><span style="color: #008000; font-size: x-small;"><br /><span style="font-size: small;"><br />/*=============================================================================================================================*/<br />--6. After ALL other steps are completed, run these to enable to cleanup job:<br />--Start distribution cleanup agent</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">USE</span></span></span><span style="font-size: small;"> <span style="color: #808080;"><span style="color: #808080;">&lt;</span></span>Distribution_DB<span style="color: #808080;"><span style="color: #808080;">,</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">varchar</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span> distribution<span style="color: #808080;"><span style="color: #808080;">&gt;</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">GO<br />EXEC</span></span></span><span style="font-size: small;"> msdb<span style="color: #808080;"><span style="color: #808080;">..</span></span><span style="color: #800000;"><span style="color: #800000;">sp_update_job</span></span><span style="color: #0000ff;"><span style="color: #0000ff;"> </span></span>@job_name <span style="color: #808080;"><span style="color: #808080;">=</span></span> <span style="color: #ff0000;"><span style="color: #ff0000;">'Distribution clean up: &lt;Distribution_DB, varchar, distribution&gt;'</span></span><span style="color: #808080;"><span style="color: #808080;">,</span></span> @enabled <span style="color: #808080;"><span style="color: #808080;">=</span></span> 1<span style="color: #808080;"><span style="color: #808080;">;</span></span></span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;"><br /><span style="font-size: small;">EXEC</span></span></span><span style="font-size: small;"> msdb<span style="color: #808080;"><span style="color: #808080;">..</span></span><span style="color: #800000;"><span style="color: #800000;">sp_start_job</span></span><span style="color: #0000ff;"><span style="color: #0000ff;"> </span></span>@job_name <span style="color: #808080;"><span style="color: #808080;">=</span></span> </span><span style="color: #ff0000;"><span style="font-size: small;"><span style="color: #ff0000;">'Distribution clean up: &lt;Distribution_DB, varchar, distribution&gt;'</span></span></span></span></span></span></p>
</p>
<p><span style="color: #ff0000;"><span style="font-size: small;"><span style="color: #ff0000;"></span><br /></span></span>
<h1><span style="color: #0000ff;"><span style="font-size: x-large;">Summary</span></span></h1>
<p><span style="font-size: medium;">Initialization from backup solves a lot of problems when trying to synchronize large databases but creates a few of its own. These problems can be mitigated with some planning and hopefully this template helps to simplify the process.</span>
<p>&nbsp;</p>
</p>
</p>]]></content:encoded>
    </item>
    <item>
      <title>SQL Server Replication: Automatic Synchronization</title>
      <link>https://docs.microsoft.com/archive/blogs/warreny/sql-server-replication-automatic-synchronization</link>
      <pubDate>Thu, 30 Dec 2010 02:46:00 GMT</pubDate>
      <dc:creator><![CDATA[Warren Y]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/warreny/2010/12/30/sql-server-replication-automatic-synchronization/</guid>
      <description><![CDATA[The simplest transactional replication synchronization scenarios involve a single publication and...]]></description>
      <content:encoded><![CDATA[<p><span style="font-size: medium;">The simplest transactional replication synchronization scenarios involve a single publication and one or more subscribers. In most cases the complexity changes very little whether or not a remote distributor is involved, so&nbsp;it's omitted in most diagrams.&nbsp;</span></p>
<h1><span style="font-size: x-large;"><span style="color: #0000ff;">Automatic Synchronization</span></span></h1>
<p><span style="font-size: medium;">This is the default scenario and the one you get if you&nbsp;create it using&nbsp;the UI. </span></p>
<h2><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/55/6840.SimplePubSub3.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-86-55/6840.SimplePubSub3.png" alt="Synchronize w Snapshot Image" style="float: left; border: 10px;" /></h2>
<h2><span style="color: #0000ff;"><span style="font-size: large;">Advantages</span></span></h2>
<ul>
<li><span style="font-size: medium;">Can be done entirely using the GUI</span></li>
<li><span style="font-size: medium;">Easiest to configure</span></li>
<li><span style="font-size: medium;">Only copies data involved with the publication</span></li>
<li><span style="font-size: medium;">Least amount of administrative effort</span></li>
</ul>
<h2><span style="font-size: x-large;"><span style="color: #0000ff;"><span style="font-size: large;"></span></span></span></h2>
<h2><span style="font-size: x-large;"><span style="color: #0000ff;"><span style="font-size: large;"></span></span></span>&nbsp;</h2>
<h2><span style="font-size: x-large;"><span style="color: #0000ff;"><span style="font-size: large;">Disadvantages</span></span></span></h2>
<ul>
<li><span style="font-size: medium;">Extremely slow, especially over long distances</span></li>
<li><span style="font-size: medium;">Causes blocking on the publisher</span></li>
<li><span style="font-size: medium;">Requires snapshot space on the distributor</span></li>
<li><span style="font-size: medium;"></span><span style="font-size: medium;">Loss of permissions on subscriber tables</span></li>
</ul>
<h2><span style="color: #0000ff;"><span style="font-size: large;"></span></span></h2>
<h2><span style="color: #0000ff;"><span style="font-size: large;"></span></span>&nbsp;</h2>
<h2><span style="color: #0000ff;"><span style="font-size: large;">Best used when</span></span></h2>
<ul>
<li><span style="font-size: medium;">Publication is small</span></li>
<li><span style="font-size: medium;">Synchronization time is unimportant</span></li>
<li><span style="font-size: medium;">Publisher, Distributor, and Subscriber in the same datacenter</span></li>
<li><span style="font-size: medium;">No long-running transactions on published tables during snapshot generation</span></li>
</ul>
<h2></h2>
<h2></h2>
<h2></h2>
<h2>&nbsp;&nbsp;</h2>
<h2><span style="font-size: x-large;"><span style="color: #0000ff;"><span style="font-size: large;">Notes</span></span></span></h2>
<ol>
<li>
<p><span style="font-size: medium;"><span style="text-decoration: underline;">Blocking</span>: Contrary to popular belief SQL server does take a Sch-M (Schema Modification) lock on published tables even with concurrent snapshot processing. What this means is that if you have some long-running selects on the table it's going to wait for those to finish before it gets its lock, and every statement behind it will be blocked as well. </span></p>
</li>
<li>
<p><span style="font-size: medium;"><span style="text-decoration: underline;">Distributor Space</span>: The main issues with large data sets involve generating the snapshot and storing it on the distributor. One thing that often happens is with multiple failed attempts the server might have several snapshots and fill the drive. If the distributor has sufficient space it might work reasonably well if the machines are geographically close together.</span></p>
</li>
<li>
<p><span style="font-size: medium;"><span style="text-decoration: underline;">Latency</span>: Long geographic distances have the most profound effect where subscriptions of only a few GB in size can take days to synchronize. Pull subscriptions generally perform better in this environment but it will still take a while to apply the snapshot and comes at the expense of having to manage replication jobs on multiple servers.</span></p>
</li>
<li>
<p><span style="font-size: medium;"><span style="text-decoration: underline;">Permission Issues</span>: Another concern with the snapshot process is permission loss. The default configuration for a publication is to drop and recreate the destination table which also removes any permissions that were on it. The most common solutions to this are to configure the published objects to truncate rather than drop and create, or configure a post snapshot script that applies any table-level permissions.</span></p>
</li>
</ol>
<h2><span style="font-size: large;"><span style="color: #0000ff;"></span></span></h2>
<h2><span style="font-size: large;"><span style="color: #0000ff;"></span></span>&nbsp;</h2>
<h2><span style="font-size: large;"><span style="color: #0000ff;">Initialization Process</span></span></h2>
<p><span style="font-size: medium;">The best part is that all work is done on the publisher and it's as simple as running sp_addsubscription. I still recommend a script even when the GUI is available especially when adding the second subscriber because there's less chance of misconfiguring, or mismatching the current subscription. Unless I'm trying to do something special with a new subscriber I create them all from a template.</span></p>
<p><span style="font-size: medium;">The first two steps in this template are for manually deleting the existing subscription. If you do this step through the GUI, you can skip the hassle of switching connections to delete the subscriber record.</span></p>
<p><span style="color: #339966;">/*===============================================================================================*/<br />/*Add Transactional snapshot subscription&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br />/*Synchronize using snapshot&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br />/*SQL 2005 or SQL 2008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br />/*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br />/*Use Ctrl-Shift-&lt;M&gt; to replace template parameters */<br />&nbsp;<br />/*===============================================================================================*/<br />--1. Run on Publisher: &lt;Publisher, varchar, PubServer&gt;<br />--In the publisher DB: &lt;PublisherDB, varchar, PubDB&gt;<br />--<br />--Steps 1 and 2 manually delete the subscription from the publisher and subscriber.<br />--If you drop the subscription through the GUI, and select the option to connect to <br />--the subscriber and delete the record, you can skip steps 1 and 2.<br />--This way you don't have to bother with opening the new query window for step 2<br /></span>&nbsp;<br /><span style="color: #0000ff;">USE</span> &lt;PublisherDB, <span style="color: #0000ff;">varchar</span>, PubDB&gt;<br /><span style="color: #0000ff;">GO</span><br />&nbsp;<br /><span style="color: #339966;">--Drop the existing subscription if present<br />--<br /></span><span style="color: #0000ff;">IF</span> EXISTS (<br />&nbsp; <span style="color: #0000ff;">SELECT</span> 1 <br />&nbsp; <span style="color: #0000ff;">FROM</span> syspublications sp<br />&nbsp; JOIN sysarticles sa <span style="color: #0000ff;">ON</span> (sp.pubid = sa.pubid)<br />&nbsp; JOIN syssubscriptions ss <span style="color: #0000ff;">ON</span> (sa.artid = ss.artid)<br />&nbsp; <span style="color: #0000ff;">WHERE</span> sp.Name = <span style="color: #ff0000;">N'&lt;Publication, varchar, PubName&gt;'<br /></span>&nbsp; AND&nbsp; ss.srvname = <span style="color: #ff0000;">N'&lt;NewSubscriber, varchar, NewSubServer&gt;'</span><br />&nbsp; AND&nbsp; ss.dest_db = <span style="color: #ff0000;">N'&lt;NewSubDB, varchar, PubDB&gt;' </span><br />)<br />&nbsp; <span style="color: #0000ff;">EXEC</span> <span style="color: #993300;">sp_dropsubscription <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @publication = <span style="color: #ff0000;">N'&lt;Publication, varchar, PubName&gt;'</span>, <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @subscriber = <span style="color: #ff0000;">N'&lt;NewSubscriber, varchar, NewSubServer&gt;'</span>, <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @destination_db =<span style="color: #ff0000;"> N'&lt;NewSubDB, varchar, PubDB&gt;'</span>,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @article=<span style="color: #ff0000;">'all'</span><br />&nbsp;<br /><span style="color: #339966;">/*===============================================================================================*/<br />--2. Run on Subscriber: &lt;NewSubscriber, varchar, NewSubServer&gt;<br />--In the Subscription DB: &lt;NewSubDB, varchar, PubDB&gt;<br />--<br />--You can skip this step if you deleted the subscription record from the GUI<br /></span><span style="color: #0000ff;">USE</span> &lt;NewSubDB, <span style="color: #0000ff;">varchar</span>, PubDB&gt;<br /><span style="color: #0000ff;">GO</span><br />&nbsp;<br />&nbsp; <span style="color: #0000ff;">EXEC</span><span style="color: #993300;"> </span><span style="color: #993300;">sp_subscription_cleanup <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @publication = <span style="color: #ff0000;">N'&lt;Publication, varchar, PubName&gt;'</span>, <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @publisher_db = <span style="color: #ff0000;">N'&lt;PublisherDB, varchar, PubDB&gt;'</span>, <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @publisher = <span style="color: #ff0000;">N'&lt;Publisher, varchar, PubServer&gt;'</span><br />&nbsp;<br /><span style="color: #339966;">/*===============================================================================================*/<br /></span>--1. Run on Publisher: &lt;Publisher, varchar, PubServer&gt;<br />--In the publisher DB: &lt;PublisherDB, varchar, PubDB&gt;<br /><span style="color: #0000ff;">USE</span> &lt;PublisherDB, <span style="color: #0000ff;">varchar</span>, PubDB&gt;<br /><span style="color: #0000ff;">GO</span><br />&nbsp;<br /><span style="color: #0000ff;">exec</span> <span style="color: #993300;">sp_addsubscription <br /></span>&nbsp; @publication = <span style="color: #ff0000;">N'&lt;Publication, varchar, PubName&gt;'</span>, <br />&nbsp; @subscriber = <span style="color: #ff0000;">N'&lt;NewSubscriber, varchar, NewSubServer&gt;'</span>, <br />&nbsp; @destination_db = <span style="color: #ff0000;">N'&lt;NewSubDB, varchar, PubDB&gt;'</span>, <br />&nbsp; @subscription_type = <span style="color: #ff0000;">N'Push'</span>, <br />&nbsp; @sync_type = <span style="color: #ff0000;">N'automatic'</span>, <br />&nbsp; @update_mode = <span style="color: #ff0000;">N'read only'</span>, <br />&nbsp; @subscriber_type = 0<br />&nbsp;<br /><span style="color: #0000ff;">exec</span> <span style="color: #993300;">sp_addpushsubscription_agent <br /></span>&nbsp; @publication = <span style="color: #ff0000;">N'&lt;Publication, varchar, PubName&gt;'</span>, <br />&nbsp; @subscriber = <span style="color: #ff0000;">N'&lt;NewSubscriber, varchar, NewSubServer&gt;'</span>, <br />&nbsp; @subscriber_db = <span style="color: #ff0000;">N'&lt;NewSubDB, varchar, PubDB&gt;'</span>, <br />&nbsp; @job_login = null, <br />&nbsp; @job_password = null, <br />&nbsp; @subscriber_security_mode = 1, <br />&nbsp; @frequency_type = 64, <br />&nbsp; @frequency_interval = 1, <br />&nbsp; @frequency_relative_interval = 1, <br />&nbsp; @frequency_recurrence_factor = 0, <br />&nbsp; @frequency_subday = 4, <br />&nbsp; @frequency_subday_interval = 5, <br />&nbsp; @active_start_time_of_day = 0, <br />&nbsp; @active_end_time_of_day = 235959, <br />&nbsp; @active_start_date = 0, <br />&nbsp; @active_end_date = 0, <br />&nbsp; @dts_package_location = <span style="color: #ff0000;">N'Distributor'</span><br />&nbsp;<br /><span style="color: #339966;">--Start the snapshot agent to start synchronizing the subscription<br /></span><span style="color: #0000ff;">exec</span> <span style="color: #993300;">sp_startpublication_snapshot</span> @publication =<span style="color: #ff0000;"> N'&lt;Publication, varchar, PubName&gt;'</span><br />&nbsp;<span style="color: #339966;">/*===============================================================================================*/</span></p>
<h1>&nbsp;</h1>
<h2><span style="font-size: large;"><span style="color: #0000ff;">Summary</span></span></h2>
<p><span style="font-size: medium;">Hopefully this helps automate some of the subscription setup process and avoid some of the more common pitfalls with using the Automatic synchronization method</span></p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>SQL Server: Transactional Replication Resynchronization</title>
      <link>https://docs.microsoft.com/archive/blogs/warreny/sql-server-transactional-replication-resynchronization</link>
      <pubDate>Mon, 27 Dec 2010 22:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Warren Y]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/warreny/2010/12/27/sql-server-transactional-replication-resynchronization/</guid>
      <description><![CDATA[Introduction
Initializing transactional replication for the first time or reinitializing when it...]]></description>
      <content:encoded><![CDATA[<h1><span style="color: #000080;"><span style="font-size: x-large;">Introduction</span></span></h1>
<p><span style="font-size: medium;"><span style="font-size: medium;">Initializing transactional replication for the first time or reinitializing when it goes out of sync can be frustrating but knowledge and planning can take most of the pain out of it. </span>This guide is designed for SQL Server database administrators to synchronize transactional replication subscriptions quickly and efficiently. It requires a working knowledge of replication and administration concepts including:</span></p>
<ul>
<li><span style="font-size: medium;">Database Backup and Restore </span>
<ul>
<li><span style="font-size: medium;">Full, Differential, and Transaction logs</span></li>
</ul>
</li>
<li><span style="font-size: medium;">Replication Concepts </span>
<ul>
<li><span style="font-size: medium;">Publisher, Distributor, and Subscribers</span></li>
<li><span style="font-size: medium;">Publications and Subscriptions</span></li>
<li><span style="font-size: medium;">Publication and subscription options</span></li>
<li><span style="font-size: medium;">Replication Agents and jobs</span></li>
</ul>
</li>
</ul>
<p><span style="font-size: medium;">If you aren't sure about these concepts I'd recommend creating a couple of regular transactional replication push publications on a non-production machine with read-only subscriptions and play around with the different settings and agent jobs.</span></p>
<p><span style="font-size: medium;">Most scenarios covered involve push replication with read-only subscribers because it tends to be the most common setup. They should work similarly for peer-to-peer and updating subscribers but would need to be updated accordingly.</span></p>
<p>&nbsp;</p>
<h1><span style="color: #000080;"><span style="font-size: x-large;">Background</span></span></h1>
<p><span style="font-size: medium;">The crux of the synchronization problem boils down to two main tasks:</span></p>
<ol>
<li><span style="font-size: medium;">Getting the initial data to the subscriber</span></li>
<li><span style="font-size: medium;">Creating the subscription metadata in the publishing, distribution, and subscription databases</span></li>
</ol>
<p><span style="font-size: medium;">The glue that binds the process together is the log sequence number (lsn) from the<i> publisher database</i> and this is how SQL server keeps track of where it's at. I tend to make a lot of references to time and what I usually mean is at a specific lsn at the publisher database. </span></p>
<p><span style="font-size: medium;">In addition to these requirements the process should meet secondary objectives:</span></p>
<ol>
<li><span style="font-size: medium;">Minimize the complexity involved with synchronization</span></li>
<li><span style="font-size: medium;">Minimize disruptive activity on the publisher</span></li>
<li><span style="font-size: medium;">Minimize impact to the business environment</span></li>
<li><span style="font-size: medium;">Minimize the time needed to synchronize</span></li>
</ol>
<p><span style="font-size: medium;">Making a mistake during initialization tends to punish harshly, typically with a lot of late nights and weekends figuring out what went wrong, how to fix it, and explaining it to downstream customers.</span></p>
<p>&nbsp;</p>
<h1><span style="color: #000080;"><span style="font-size: x-large;">Getting the initial dataset to the subscriber</span></span></h1>
<p><span style="font-size: medium;">This process starts by getting a consistent snapshot of all of the articles from <i>the same </i>point in time at the publisher and applying it to the new subscriber. Usually this is done by the snapshot agent or from a database backup. It could also be done by directly copying tables but this tends to be time consuming and also introduces the problem of data consistency since you can synchronize the entire process to a specific lsn. There's a possibility of using a backup from a different database (perhaps another subscriber), but we can't use the lsn from that file since lsns are specific to an instance of a database and we require the lsn from the publisher. </span></p>
<p><span style="font-size: medium;">Just as important is ensuring that transactions after the initial lsn and before the initial synchronization are not lost. The worst part about this is that we usually don't discover this until we try to create the subscription and get a message that looks something like this:</span></p>
<p><span style="font-size: medium;"><span style="color: #ff0000;"><span style="font-family: Courier New;"><span style="font-size: small;">Msg 21397<br />The transactions required for synchronizing the nosync subscription created from the specified backup are unavailable at the Distributor. Retry the operation again with a more up-to-date log, differential, or full database backup.</span></span></span></span></p>
<p><span style="font-size: medium;">The usual suspects for missing data in this time frame are:&nbsp;</span></p>
<ol>
<li><span style="font-size: medium;"><span style="text-decoration: underline;">Publication doesn't exist</span>: The publication needs to exist so that there is a start point for synchronization, and it needs to have existed before the time the initial data snapshot is taken. </span></li>
<li><span style="font-size: medium;"><span style="text-decoration: underline;">Distribution Cleanup Agent</span>: This is the job that runs on the distributor and dutifully cleans up transactions that have already been applied at all subscribers. The problem occurs because the minimum transaction retention period is set to 0 by default. Since the subscription usually does not yet exist while copying the data, it removes the transactions as soon as all of the other subscribers have applied them. You can disable this job during the process, or you can set a minimum retention time.&nbsp;&nbsp;</span></li>
</ol>
<table cellpadding="0" cellspacing="0" style="width: 100%;">
<tbody>
<tr>
<td>
<p><span style="font-size: medium;">&nbsp;<img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/55/3022.DistProp2.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-86-55/3022.DistProp2.png" border="0" /></span></p>
</td>
</tr>
</tbody>
</table>
<p sizset="0" sizcache="2"><span style="font-size: medium;">The number of commands between the lsn of the backup and the current lsn at first synchronization is critical because all of that information needs to be stored at the distributor until it's applied. The more commands waiting the worse the performance will be when SQL reads, applies, and then cleans up this chunk of data. This is why it's important to minimize the synchronization time as much as possible. This is also a reason against having a large minimum retention time.</span></p>
<p sizset="0" sizcache="2"><span style="font-size: medium;">Since we can synchronize from any backup file including a transaction log backup, the easiest trick to minimize the time lag is to restore differential and logs to bring the database as close to the current time as possible. The other bonus is that these operations are largely parallelizable since we can copy the diff and log files at the same time the full is restoring.</span></p>
<p sizset="0" sizcache="2"><span style="font-size: medium;">A second important trick to minimizing time lag is to create scripts while the data is copying / restoring and have them ready to execute when the database is restored.</span></p>
<p sizset="0" sizcache="2"><span style="font-size: medium;"></span></p>
<p sizset="0" sizcache="2"><span style="font-size: x-large;"></span></p>
<h1 sizset="0" sizcache="2"><span style="color: #000080;"><span style="font-size: x-large;">Creating the publication and subscriptions</span></span></h1>
<p sizset="0" sizcache="2"><span style="font-size: medium;">Implementing a subscription with any kind of nontrivial synchronization plan requires a lot of verbose scripting and even simple implementations should be scripted for disaster recovery and maintenance purposes. One easy way to do this is by creating something close to what you want in the GUI and using 'Generate Scripts...' on the publication to make scripts which are then modify to a scenario. Keep the entire script for disaster recovery but for the purposes of syncing a new subscriber we are generally only interested in the last two lines:</span></p>
<p><span style="font-size: x-small;"><span style="font-family: courier new,courier;"><span style="font-size: small;"></span></span></span></p>
<p><code class="mysql"><span style="font-size: x-small;"><span style="font-family: courier new,courier;"><span style="font-size: small;"><span style="color: #0000ff;">exec</span> <span style="color: #993300;">sp_addsubscription</span> @publication =<span style="color: #ff0000;"> N'MyPub'</span>, @subscriber = <span style="color: #ff0000;">N'Subserver'</span>[...] <br /><span style="color: #0000ff;">exec</span> <span style="color: #993300;">sp_addpushsubscription_agent</span> @publication = <span style="color: #ff0000;">N' MyPub'</span>, @subscriber = [...]</span></span></span></code></p>
<p sizset="0" sizcache="2"><span style="font-size: medium;">Another way is to create templates that support a specific scenario, then use the 'Replace Parameters' function to fill in the Publisher, Subscribers, etc. In addition to saving time these templates reduce the odds of forgetting a critical step during the process which usually results in starting over from the beginning.</span></p>
<p><span style="font-size: medium;">The time between determining the initial lsn and creating the subscription is critical because modifications during this period can cause SQL to reject an lsn as unsuitable. Furthermore, starting or stopping replication agents during the process can cause data loss depending on the specific scenario. Being unsure about whether the sync process lost data is often worse than just choosing different sync method because validating that two large distributed data sets are the same can be costly.</span></p>
<p><span style="font-size: medium;">SQL 2005 allows no-sync types of 'replication support only' and 'initialize with backup' which limits our options for lsns we can start from. 'Replication Support Only' requires that publisher and subscriber have identical data (i.e. quiesced). 'Initialize with Backup' allows us to start from a different lsn, but not any arbitrary one. SQL 2008 allows option 'initialize from lsn' which does allow any arbitrary <i>valid</i> lsn to be used.</span></p>
<p><span style="font-size: medium;">A tempting workaround for the SQL 2005 issue is to create a subscription with a different lsn, and then immediately update it before first synchronization with something like:</span></p>
<p><span style="font-size: x-small;"><span style="font-family: courier new,courier;"><span style="font-size: small;"><span style="color: #000080;"><span style="color: #0000ff;">EXEC</span> </span><span style="color: #993300;">sp_setsubscriptionxactseqno</span> <span style="color: #ff0000;">'Publisher'</span>, <span style="color: #ff0000;">'PubDB'</span>, <span style="color: #ff0000;">'Publication'</span>, <span style="color: #000000;">&lt;</span>My_arbitrary_lsn&gt; </span></span></span></p>
<p><span style="font-size: medium;">The difficulty with this approach is that the distribution agent is what sets up the subscription, after which it immediately begins synchronizing. If a method depends on starting exactly from this lsn then there is a risk of introducing data inconsistencies for records applied between the original lsn and the updated one.&nbsp; </span></p>
<p><span style="font-size: medium;">It <i>might</i> be possible to try manipulating the lsn by creating the initial subscription with frequency_type = 2 (on demand) so that it doesn't automatically start and then change the subscription_seqno number in the MSSubscriptions table on the distributor. Unfortunately, every experiment I've tried with this has resulted in lost transactions so I wouldn't recommend it, but there are some other ways to work around the problem.</span></p>
<p><span style="font-size: medium;"></span></p>
<p><span style="font-size: x-large;"></span></p>
<h1><span style="font-size: large;"><span style="color: #000080;"><span style="font-size: x-large;">Summary</span></span></span></h1>
<p><span style="font-size: medium;">Synchronizing transactional replication subscriptions involves getting all of the replicated tables to the subscriber with the least amount of effort and disruption. Once everything is in place it becomes a matter of creating the subscription and letting SQL know which lsn it should start processing from.</span></p>
<p><span style="font-size: medium;">In&nbsp;the coming weeks&nbsp;I will&nbsp;post info about&nbsp;common replication scenarios and some methods for doing them.</span></p>]]></content:encoded>
    </item>
  </channel>
</rss>