<?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>AlwaysOn Professional</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/alwaysonpro/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/alwaysonpro/feed.xml</link>
    <description>Home of the Microsoft SQL Server AlwaysOn Support Team</description>
    <lastBuildDate>Thu, 08 Mar 2018 17:23:08 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Analyze Synchronous Commit Impact on High Commit Rate Workloads</title>
      <link>https://docs.microsoft.com/archive/blogs/alwaysonpro/analyze-synchronous-commit-impact-on-high-commit-rate-workloads</link>
      <pubDate>Tue, 06 Feb 2018 15:49:30 GMT</pubDate>
      <dc:creator><![CDATA[AlwaysOn Professionals]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alwaysonpro/?p=4235</guid>
      <description><![CDATA[Workloads that rely on auto-commit (each operation like an INSERT has an implied, corresponding...]]></description>
      <content:encoded><![CDATA[<p>Workloads that rely on auto-commit (each operation like an INSERT has an implied, corresponding begin and commit transaction) and perform a large number of small transactions may take significantly longer to complete when run against availability group databases configured for synchronous commit. Aside from an issue with resource latency (IO, CPU or network) this performance impact may be expected. </p><h3>Synchronous Commit Emphasizes Minimizing Data Loss Over Performance</h3><p>Synchronous commit availability mode is desirable when minimizing data loss is paramount for your high availability solution and prioritizes Recovery Point Objective over performance.</p><p>In the following link, it says this about synchronous commit.</p><blockquote><p><a title="https://docs.microsoft.com/en-us/sql/database-engine/availability-groups/windows/availability-modes-always-on-availability-groups" href="https://docs.microsoft.com/en-us/sql/database-engine/availability-groups/windows/availability-modes-always-on-availability-groups">Availability Modes (Always On Availability Groups)</a></p></blockquote><blockquote><p><em>Synchronous-commit mode</em> emphasizes high availability over performance, at the cost of increased transaction latency. Under synchronous-commit mode, transactions wait to send the transaction confirmation to the client until the secondary replica has hardened the log to disk.</p></blockquote><p>This blog will demonstrate how to measure the performance impact on a high transaction rate workload that is dependent on auto-commit behavior in SQL Server and how explicitly defining transactions in that same workload can mitigate the impact and provide better performance.</p><h3>The Transaction Must be Written at the Primary and The Synchronous Secondary To Commit</h3><p>To illustrate the impact of synchronous commit, take a simple INSERT command initiated on a database at the primary replica. That insert must be hardened on the transaction log file of the primary replica <em>and</em> of the transaction log file on the secondary replica and then acknowledgement must arrive from both replicas before SQL Server can commit the transaction. When performing hundreds of these commands a second in a workload, the impact performance can be significant.</p><p>For more internal details on how synchronous commit works, see the following blog:</p><blockquote><p><a title="https://blogs.msdn.microsoft.com/psssql/2011/04/01/alwayson-hadron-learning-series-how-does-alwayson-process-a-synchronous-commit-request/" href="https://blogs.msdn.microsoft.com/psssql/2011/04/01/alwayson-hadron-learning-series-how-does-alwayson-process-a-synchronous-commit-request/">AlwaysON – HADRON Learning Series:&nbsp; How does AlwaysON Process a Synchronous Commit Request</a></p></blockquote><h2></h2><h2></h2><h3>Demo – Measure Workload Performance in Synchronous Commit</h3><p>Let’s demonstrate the impact of auto-commit mode when executing a workload against an availability group database configured for synchronous commit, and how to measure the throughput.</p><p><br></p><h4>Enable Performance Monitor Counters</h4><p>Enable the following counters in performance monitor on the primary replica:</p><blockquote><p>For availability group database agdb in our example:<br>&nbsp;&nbsp;&nbsp; SQL Server:Databases:Log Bytes Flushed/sec<br>&nbsp;&nbsp;&nbsp; SQL Server:Databases:Log Flushes/sec<br>&nbsp;&nbsp;&nbsp; SQL Server:Databases:Write Transactions/sec<br>&nbsp;&nbsp;&nbsp; SQL Server:Database Replica:Transaction Delay</p></blockquote><p><a href="https://msdnshared.blob.core.windows.net/media/2018/02/image66.png"><img width="720" height="517" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/02/image_thumb33.png" border="0"></a></p><p><br></p><h4>Run the workload, observe execution time, estimate transaction performance</h4><p>The following workload inserts 10,000 rows 10 times, and uses auto-commit behavior, which will result in 100,000 transactions. It will report the average time it took to insert 10,000 rows in seconds and the average time it took to insert a single row in milliseconds.</p><blockquote><p><font size="1">use agdb<br> go</font></p><font size="1"></font><p><font size="1">declare @y int=0<br> declare @x int=0<br> declare @starttime datetime<br> declare @endtime datetime<br> create table test (col int)<br> create table results (duration float)</font></p><font size="1"></font><p><font size="1">while @x&lt;10<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set @starttime =getdate()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while @y&lt;10000</font></p><font size="1"></font><p><font size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<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; insert test (col)<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; select @y<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; set @y=@y+1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end&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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set @endtime =getdate()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insert results (duration)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select datediff(millisecond,@starttime, @endtime)/1000.0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set @x=@x+1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set @y=0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end</font></p><font size="1"></font><p><font size="1">select * from results<br>select avg(duration) as 'avg duration in sec for 10,000 INSERTs', avg(duration)/10 as 'avg duration in ms for each INSERT' from results</font></p><font size="1"></font><p><font size="1">drop table results<br> drop table test</font></p><p><font size="1"></font></p></blockquote><p>After we create our availability group and database, and configure it for synchronous commit with a single secondary replica, we run our workload. The report is that our average INSERT took 4.4 ms to complete the round trip, getting hardened on the log file at the primary and secondary replicas. The batch took 7 minutes 50 seconds to complete.</p><div><br></div>
<p><a href="https://msdnshared.blob.core.windows.net/media/2018/02/image67.png"><img width="855" height="685" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/02/image_thumb34.png" border="0"></a></p><p><br></p><h4>HADR_SYNC_COMMIT waittype reports synchronous commit latency</h4><p>HADR_SYNC_COMMIT wait type measures the latency when performing transactions in an availability group database when configured for synchronous commit. To reset the instance’s waittype counter values (they accumulate over time), execute the following to clear the data:</p><blockquote><p>DBCC SQLPERF('sys.dm_os_wait_stats' , CLEAR) </p></blockquote><p>Test to demonstrate the severity of this waittype on the instance. There is a large number of these waits reported.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2018/02/image68.png"><img width="855" height="316" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/02/image_thumb35.png" border="0"></a></p><p><br></p><h4>Review the performance monitor counters</h4><p>Let’s review the performance monitor counters collected during the batch. Log Bytes Flushed/sec for the database is pretty low, less than 1 mb/sec.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2018/02/image69.png"><img width="659" height="473" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/02/image_thumb36.png" border="0"></a></p><p><br></p><p><strong>Compare Log Flushes/sec to Write Transactions/sec</strong> For every write transaction performed, there is a flush to disk. This is what we would expect in auto-commit mode. Here we see 211 transactions are completing every second and for each transaction there is a corresponding flush to disk, on the database log file at the primary replica and on the database log file at the secondary replica.</p><p><table width="600" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td width="300" valign="top"><a href="https://msdnshared.blob.core.windows.net/media/2018/02/image70.png"><img width="549" height="397" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/02/image_thumb37.png" border="0"></a></td>
<td width="300" valign="top"><a href="https://msdnshared.blob.core.windows.net/media/2018/02/image71.png"><img width="555" height="399" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/02/image_thumb38.png" border="0"></a></td>
</tr>
</tbody>
</table>
<p><br></p><h4>Confirm estimated transaction time using performance monitor</h4><p>The workload reported ‘avg duration for each transaction in MS’ as 4.4 ms.&nbsp; We can use performance monitor to make a second confirmation calculation that this is accurate: divide one second by an average of 211 Write Transactions performed in a second, which is 1/211=.0047 seconds or 4.7 ms. This number is very similar to the number that our workload results reported. This is the time it took to capture the log change, deliver it to the secondary, write it to the log file on the primary and secondary and report back to the client that it is complete.</p><h2>Do not Depend on Auto-Commit - Define Explicit Transactions</h2><p>The batch has been modified with an explicit transaction in the workload in such a way that 10,000 INSERT operations will be committed together. This is much more efficient considering the requirements of synchronous commit, that each transaction requires the hardening of the operation to the log files of each replica and the network round trip needed to accomplish that work. Note the BEGIN TRAN and COMMIT TRAN commands added to the batch and commented.</p><h4>Run the workload using explicit transactions, observe execution time, estimate transaction performance</h4><blockquote><p><font size="1">use agdb<br> go</font></p><font size="1"></font><p><font size="1">declare @y int=0<br> declare @x int=0<br> declare @starttime datetime<br> declare @endtime datetime<br> create table test (col int)<br> create table results (duration float)</font></p><font size="1"></font><p><font size="1">while @x&lt;10<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set @starttime =getdate()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font>begin tran&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; <strong>--BEGIN 10000 row transaction</strong></font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while @y&lt;10000</font></p><font size="1"></font><p><font size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<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; insert test (col)<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; select @y<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; set @y=@y+1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end&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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font>commit tran&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; <strong> --COMMIT 10000 row transaction</strong></font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set @endtime =getdate()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insert results (duration)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select datediff(millisecond,@starttime, @endtime)/1000.0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set @x=@x+1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set @y=0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end</font></p><font size="1"></font><p><font size="1">select * from results<br> select avg(duration) as 'avg duration in sec for 10,000 INSERTs', avg(duration)/10 as 'avg duration in ms for each INSERT' from results</font></p><font size="1"></font><p><font size="1">drop table results<br> drop table test</font></p><p><font size="1"></font></p></blockquote><p>Our results are almost instantaneous. The results completed in a couple seconds!</p><p><a href="https://msdnshared.blob.core.windows.net/media/2018/02/image72.png"><img width="855" height="685" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/02/image_thumb39.png" border="0"></a></p><p><br></p><h4>HADR_SYNC_COMMIT waittype reports synchronous commit latency</h4><p>Having reset the SQL Server wait counters using DBCC SQLPERF (described earlier) we see HADR_SYNC_COMMIT waits are significantly lower. </p><p><a href="https://msdnshared.blob.core.windows.net/media/2018/02/image73.png"><img width="855" height="628" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/02/image_thumb40.png" border="0"></a></p><p><br></p><h4>Review the performance monitor counters</h4><p>Reviewing performance monitor, Log Bytes Flushed/sec spiked to 10.4 mb/sec versus our earlier test in which it averaged less than 1 mb/sec. This shows how much more throughput SQL Server is able to accomplish when not committing a few bytes for individually small transactions.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2018/02/image74.png"><img width="669" height="483" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/02/image_thumb41.png" border="0"></a></p><p>When comparing Log Flushes/sec to Write Transactions/sec the correlation is not as clear. During batch execution, Log Flushes/sec spike to 181, and Write Transactions are much lower, since the workload itself performed only 10 explicit transactions instead of 100,000.</p><table width="600" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td width="300" valign="top"><a href="https://msdnshared.blob.core.windows.net/media/2018/02/image471.png"><img width="546" height="395" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/02/image47_thumb.png" border="0"></a></td>
<td width="300" valign="top"><a href="https://msdnshared.blob.core.windows.net/media/2018/02/image75.png"><img width="551" height="396" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/02/image_thumb42.png" border="0"></a></td>
</tr>
</tbody>
</table>
<p><a href="https://msdnshared.blob.core.windows.net/media/2018/02/image75.png"><br></a></p><h3>Conclusion </h3><p>Synchronous commit can introduce latency to your high transaction workloads, this can be especially impactful in environments that must complete large ETL batches on the weekends or overnight in order to prepare the data for the next business day. Using explicit transactions can optimize workload performance and still take advantage of the strengths synchronous commit offers (eliminate data loss).</p>]]></content:encoded>
    </item>
    <item>
      <title>Analyze Network Latency Impact on Remote Availability Group Replica</title>
      <link>https://docs.microsoft.com/archive/blogs/alwaysonpro/analyze-network-latency-impact-on-remote-availability-group-replica</link>
      <pubDate>Thu, 21 Dec 2017 15:34:34 GMT</pubDate>
      <dc:creator><![CDATA[AlwaysOn Professionals]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alwaysonpro/?p=4035</guid>
      <description><![CDATA[Multisite availability groups allow customers to deploy copies of business data across multiple...]]></description>
      <content:encoded><![CDATA[<p>Multisite availability groups allow customers to deploy copies of business data across multiple sites, for disaster recovery and/or for reporting purposes, offering near real-time changes available to the copies of the production data at remote locations.</p><p>If secondary replicas are hosted greater distances from the primary replica, network latency can begin to impact availability group synchronization’s ability to keep the secondary up to date with the changes made at the primary replica. </p><p><br></p><h3>Symptom - Sustained or Growing Log Send Queue </h3><p>When network latency becomes an issue the most common symptom you will observe is sustained or growing log send queue. Simply defined, log send queue is the changes stored in the transaction log of your availability group database on the primary replica that have not yet arrived and hardened to the transaction log of the availability group on the secondary replica.</p><p>Why should you care? The log send queue represents all the data that can be lost from a catastrophic failure. If your primary replica was lost in a sudden disaster, and you were forced to fail over to the secondary replica where these changes have not yet arrived, your business would incur data loss.</p><p>Log send queue is a per-database measurement. Here are ways you can actively monitor your availability group database log send queue.</p><p><strong>Add the Log Send Queue size (KB) column in AlwaysOn Dashboard</strong> In SQL Server Management Studio Object Explorer, right click on your availability group and choose Show Dashboard. The dashboard will appear in the right pane. Right-click the column header above the list of databases in your availability group and choose to add Log Send Queue Size (KB).</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/12/image366.png"><img width="855" height="337" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb351.png" border="0"></a></p><p><br></p><p>The column is added and reports the current queue size in KB.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/12/image367.png"><img width="855" height="235" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb352.png" border="0"></a></p><p><br></p><p><strong>Add the SQLServer:Database Replica:Log Send Queue Counter</strong> On the secondary replica, add the SQLServer:Database Replica:Log Send Queue counter for the database instance whose log send queue you are monitoring.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/12/image368.png"><img width="788" height="432" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb353.png" border="0"></a></p><p><br></p><h3>Measure Network Latency Impact Using Performance Monitor</h3><p>In the following demo we measure the impact of network latency on log send queue growth. We can use SQL Server performance monitor counters on the primary and secondary replicas during synchronization of a load which results in log send queue growth. Compression is disabled during this load test in order to put more load on the network.</p><p>On the secondary replica, launch Performance Monitor and add the following counters:</p><blockquote><p>SQLServer:Database Replica:Log Bytes Received/sec <i>for appropriate database instance</i></p><p>SQLServer:Database Replica:Recovery Queue <em>for appropriate database instance</em></p></blockquote><p>On the primary replica, launch Performance Monitor and add the following counters:</p><blockquote><p>SQLServer:Databases:Log Bytes Flushed/sec <em>for appropriate database instance</em></p><p>Network Interface:Sent Bytes/sec <em>for appropriate adapter instance</em></p></blockquote><p>Once you have Performance Monitor running, initiate the load that leads to log send queuing, and monitor the counters.</p><p>Review the performance monitor counters on the secondary, we can see Log Bytes Received/sec for our availability group database is averaging 2.1 mb/sec. Note that the Log Send Queue for the database is continually growing meaning that there are a growing number of changes that have occurred at the primary replica that are stored in the transaction log there that have not yet arrived and hardened on the transaction log of the local database on the secondary replica.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/12/image369.png"><img width="801" height="422" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb354.png" border="0"></a></p><p><br></p><p>Now, on the primary replica, check the availability group database’s Log Bytes Flushed/sec. We see that our load is generating and hardening on average 7.1 mb/sec to the local transaction log.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/12/image370.png"><img width="811" height="448" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb355.png" border="0"></a></p><p><br></p><p>Clearly, if we are generating over 7 mb/sec of logged changes at the primary but only receiving 2 mb/sec of changes at the secondary, we can expect log send queue growth. These observations can lead us to begin to consider network latency as a possible cause for our growing log send queue.</p><p>On the primary, check the Network Interface:Bytes Sent/sec for the correct network adapter instance. On average, the primary is sending 2.2 mb/sec, and we can expect that nearly all of that is to the secondary replica where we observed comparable Log Bytes Received/sec.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/12/image371.png"><img width="821" height="457" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb356.png" border="0"></a></p><p><br></p><h3>Measure your network throughput independently of SQL Server</h3><p>In order to better understand how fast an application can push changes to the remote server, use a third party network bandwidth performance tool, like iPerf or NTttcp. The following demo is using iPerf on the same operating environment as the prior demo.</p><p>These tools use a default port to communicate with each other, so it may be necessary to open that port, in the case of iPerf, it uses 5201 by default.</p><p><strong>IMPORTANT</strong> It is important to configure the tool to use a single connection to send data, since SQL Server <em>uses a single connection to send synchronization changes</em> from the primary to the secondary replica. </p><h4></h4><h4>Test network throughput with iPerf</h4><p>On the remote secondary replica, launch iPerf with the –s parameter and it will begin to listen for a connection over port 5201.</p><blockquote><p>iperf3 –s</p></blockquote><p><a href="https://msdnshared.blob.core.windows.net/media/2017/12/image372.png"><img width="643" height="438" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb357.png" border="0"></a></p><p><br></p><p>On the SQL Server hosting the primary replica, launch iPerf using the following parameters, and it will begin a transmission with the remote SQL Server.</p><p>Here are the parameters.</p><blockquote><p>-c ip address of destination server<br>
–P 1 Use a single connection in the test<br>
–t 10 Perform 10 one second transfers </p></blockquote><p>Here is the command line;<br>
</p><blockquote><p>iperf –c &lt;&lt;secondaryipaddress&gt;&gt; –t 10 –P 1</p></blockquote><p>iPerf is reporting it can send between 2.12 and 2.50 mb/sec to the remote secondary server. This rate is very comparable to the rates we observed above in our load test using SQL Server.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/12/image373.png"><img width="639" height="493" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb358.png" border="0"></a></p><p><br></p><h3></h3><p>Testing a server that is closer to your primary replica can provide a useful foil when doing this test. Below, I run the same test from the primary this time to a destination server in the same data center and subnet as the primary server. Here are the test results, noticeably higher throughput when the destination server is in closer proximity and same subnet.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/12/image374.png"><img width="646" height="561" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb359.png" border="0"></a></p><p><br></p><h4>Test network throughput with NTttcp</h4><p>Below is a demonstration of using NTttcp.exe in the same environment as above.</p><p>On the remote secondary replica (the receiver), launch NTttcp as follows, here –m 1 is for single threaded, and the IP address of the local receiver server.</p><blockquote><p>NTttcp.exe –r –m 1,0,10.1.0.4 –rb 2M –a 16</p></blockquote><p><a href="https://msdnshared.blob.core.windows.net/media/2017/12/image375.png"><img width="678" height="468" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb360.png" border="0"></a></p><p>On the primary replica (the sender), initiate the test by executing the following, again supplying the IP address of the receiver. This test is for 10 seconds (-t 10):</p><blockquote><p>NTttcp.exe –s –m 1,0,10.1.0.4 –l 128k –a 16 –t 10</p></blockquote><p>The results report about 2.7 mb/sec which is similar to the testing results obtained from iPerf and from our performance monitor log.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/12/image376.png"><img width="685" height="594" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb361.png" border="0"></a></p><h3>In Conclusion</h3><p>This testing can help you to determine if network latency is impacting log send queue for remote asynchronous replicas in your availability group. Log send queuing can impact your recovery point objective (RPO) and as described earlier in this blog translate to potential data loss.</p><p>For more information on recovery point objective and the potential for data loss see </p><blockquote><p><a href="https://msdn.microsoft.com/en-us/library/dn135338(v=sql.110).aspx">Monitor Performance for AlwaysOn Availability Groups</a></p></blockquote><p>If you find that network latency is having an impact, consider using netsh or another network trace tool to check for retransmits, dropped packets, etc.</p>]]></content:encoded>
    </item>
    <item>
      <title>Availability Group Database Reports Not Synchronizing / Recovery Pending After Database Log File Inaccessible</title>
      <link>https://docs.microsoft.com/archive/blogs/alwaysonpro/availability-group-database-reports-not-synchronizing-recovery-pending</link>
      <pubDate>Wed, 29 Nov 2017 17:14:26 GMT</pubDate>
      <dc:creator><![CDATA[AlwaysOn Professionals]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alwaysonpro/?p=3525</guid>
      <description><![CDATA[&nbsp;

You may find that one or more availability group databases is reported ‘Not Synchronizing...]]></description>
      <content:encoded><![CDATA[&nbsp;

You may find that one or more availability group databases is reported<strong> ‘Not Synchronizing / Recovery Pending’ on the primary replica</strong> or <strong>‘Not Synchronizing’ on one of the secondary replicas</strong>. Despite this, your availability group replicas report they are in the primary role or secondary role,

This may occur if SQL Server is unable to access the database log files of your availability group database(s). The following blog describes the symptoms, cause and resolution for this problem when encountered on the primary or secondary replicas of your availability group.

&nbsp;
<h3>Symptoms of Availability Group Database on Primary Replica</h3>
<h4>Primary Replica Database Reported Not Synchronizing / Recovery Pending</h4>
In SQL Server Management Studio’s Object Explorer, on the primary replica, the availability group database may be reported as ‘Not Synchronizing/Recovery Pending:

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/p16.png"><img width="356" height="386" title="p1" alt="p1" src="https://msdnshared.blob.core.windows.net/media/2017/11/p1_thumb.png" border="0" /></a>

&nbsp;
<h4></h4>
<h4>Primary Replica - Attempts to Access Database or Perform DML Fail</h4>
Attempts to access the affected database will fail. For example, an attempt to INSERT into a table in that database reports 9001, ‘The log for database…is not available.’

SQL Server Management Studio will report the database in ‘Not Synchronizing / Recovery Pending’ state.

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/p21.png"><img width="828" height="347" title="p2" alt="p2" src="https://msdnshared.blob.core.windows.net/media/2017/11/p2_thumb.png" border="0" /></a>

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/image387.png"> </a>
<h3>Cause SQL Server unable to access database log file</h3>
This availability group database state could have been caused because SQL Server could not access the log file and or data file(s). In the event the log file is or was inaccessible, SQL Server will offline the database and report the database in Recovery Pending state. In this scenario, the database is defined in an availability group, and therefore will be reported in SQL Server Management Studio as ‘Not Synchronizing / Recovery Pending. Check the SQL Server error log to determine if this is the cause for reporting the Recovery Pending state. You will find a message 9001 reported that the ‘log for database xxx is not available.’
<blockquote><span style="font-size: xx-small">2017-07-13 06:42:44.74 spid1s      Error: 17053, Severity: 16, State: 1.
2017-07-13 06:42:44.74 spid1s      SQLServerLogMgr::LogWriter: Operating system error 21(The device is not ready.) encountered.
2017-07-13 06:42:44.74 spid1s      Write error during log flush.
2017-07-13 06:42:44.75 spid51      Error: 9001, Severity: 21, State: 4.
2017-07-13 06:42:44.75 spid51      The log for database 'testdb' is not available. Check the event log for related error messages. Resolve any errors and restart the database.
2017-07-13 06:42:44.75 spid51      State information for database 'testdb' - Hardened Lsn: '(34:840:1)'    Commit LSN: '(34:824:2)'    Commit Time: 'Jul 12 2017  1:19PM'
2017-07-13 06:42:44.75 spid23s     Always On Availability Groups connection with secondary database terminated for primary database 'testdb' on the availability replica 'SN2' with Replica ID: {10b9a12b-afed-48f3-b79c-9ecc5cada754}. This is an informational message only. No user action is required.
2017-07-13 06:42:44.75 spid51      Database testdb was shutdown due to error 9001 in routine 'XdesRMFull::CommitInternal'. Restart for non-snapshot databases will be attempted after all connections to the database are aborted.
2017-07-13 06:42:44.77 spid18s     State information for database 'testdb' - Hardened Lsn: '(34:840:1)'    Commit LSN: '(34:824:2)'    Commit Time: 'Jul 12 2017  1:19PM'
2017-07-13 06:42:44.86 spid18s     Error: 17053, Severity: 16, State: 1.
2017-07-13 06:42:44.86 spid18s     fcb::close-flush: Operating system error (null) encountered.</span></blockquote>
<h4></h4>
<h3>Resolve Primary Replica Database Not Synchronizing / Recovery Pending</h3>
A thought might be to suspend and resume the availability group database but this will not solve this issue. Resume does not initiate recovery on the database, which is what is necessary to bring the database back into an online state.

Once you have confirmed the database files are accessible, use the ALTER DATABASE SET ONLINE command to initiate the recovery of the database which should bring the database online.
<blockquote><span style="font-size: xx-small">use master
go
alter database testdb set online
go</blockquote>
Here we online the database and now the database is once again online and in a Synchronized state.

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/p31.png"><img width="823" height="332" title="p3" alt="p3" src="https://msdnshared.blob.core.windows.net/media/2017/11/p3_thumb.png" border="0" /></a>

The error log shows SQL Server go through recovery and re-establish connection with secondary replica.
<blockquote><span style="font-size: xx-small">2017-07-13 06:57:41.97 spid58      Setting database option ONLINE to ON for database 'testdb'.
2017-07-13 06:57:41.97 spid58      State information for database 'testdb' - Hardened Lsn: '(34:856:1)'    Commit LSN: '(34:824:2)'    Commit Time: 'Jul 12 2017  1:19PM
2017-07-13 06:57:41.97 spid58      State information for database 'testdb' - Hardened Lsn: '(34:856:1)'    Commit LSN: '(34:824:2)'    Commit Time: 'Jul 12 2017  1:19PM'
2017-07-13 06:57:42.00 spid58      State information for database 'testdb' - Hardened Lsn: '(34:856:1)'    Commit LSN: '(34:824:2)'    Commit Time: 'Jul 12 2017  1:19PM'
2017-07-13 06:57:42.00 spid58      Starting up database 'testdb'.
2017-07-13 06:57:42.17 spid58      2 transactions rolled forward in database 'testdb' (9:0). This is an informational message only. No user action is required.
2017-07-13 06:57:42.27 spid30s     0 transactions rolled back in database 'testdb' (9:0). This is an informational message only. No user action is required.
2017-07-13 06:57:46.98 spid36s     Always On Availability Groups connection with secondary database established for primary database 'testdb' on the availability replica 'SN2' with Replica ID: {10b9a12b-afed-48f3-b79c-9ecc5cada754}. This is an informational message only. No user action is required.</span></blockquote>
<h4></h4>
<h3>Symptoms of Availability Group Database on Secondary Replica</h3>
&nbsp;
<h4>Secondary Replica Database Reported Not Synchronizing</h4>
If SQL Server hosting the <strong>secondary replica</strong> is unable to access availability group database files, database is marked in the <strong>Not Synchronizing </strong>state. Note that sys.dm_hadr_database_replica_states and sys.databases still reports the database as Online.

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/p41.png"><img width="761" height="332" title="p4" alt="p4" src="https://msdnshared.blob.core.windows.net/media/2017/11/p4_thumb.png" border="0" /></a>

&nbsp;
<h4>Secondary Replica – Attempts to Suspend and Resume synchronization Fail</h4>
This might be your first instinct, when seeing an availability group database reported as ‘Not Synchronizing’ in SSMS. Even if the database log file becomes accessible again, synchronization is not resumed. Attempting to Suspend and then Resume will both appear to succeed:

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/p52.png"><img width="750" height="464" title="p5" alt="p5" src="https://msdnshared.blob.core.windows.net/media/2017/12/p5_thumb.png" border="0" /></a>

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/p6.png"><img width="745" height="461" title="p6" alt="p6" src="https://msdnshared.blob.core.windows.net/media/2017/12/p6_thumb.png" border="0" /></a>

&nbsp;

However, querying sys.dm_hadr_database_replica_states will report that the database still is not synchronizing and the database is still reported Not Synchronizing in SSMS Object Explorer.

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/p7.png"><img width="758" height="324" title="p7" alt="p7" src="https://msdnshared.blob.core.windows.net/media/2017/12/p7_thumb.png" border="0" /></a>

&nbsp;
<h3>Cause SQL Server unable to access database log file</h3>
Again, confirm if the current availability group issue resulted when SQL Server was unable to access the database files. The error log on the secondary reports the problem during redo (term for availability group ongoing recovery of secondary availability group database) accessing log file and so the database is suspended.
<blockquote><span style="font-size: xx-small">2017-07-13 07:07:20.01 spid1s      Error: 17053, Severity: 16, State: 1.
2017-07-13 07:07:20.01 spid1s      SQLServerLogMgr::LogWriter: Operating system error 21(The device is not ready.) encountered.
2017-07-13 07:07:20.01 spid1s      Write error during log flush.
2017-07-13 07:07:20.01 spid25s     Error: 9001, Severity: 21, State: 5.
2017-07-13 07:07:20.01 spid25s     The log for database 'testdb' is not available. Check the event log for related error messages. Resolve any errors and restart the database.
2017-07-13 07:07:20.19 spid25s     Error: 3313, Severity: 21, State: 2.
2017-07-13 07:07:20.19 spid25s     During redoing of a logged operation in database 'testdb', an error occurred at log record ID (34:896:1). Typically, the specific failure is previously logged as an error in the Windows Event Log service. Restore the database from a full backup, or repair the database.
2017-07-13 07:07:20.38 spid25s     Always On Availability Groups data movement for database 'testdb' has been suspended for the following reason: "system" (Source ID 2; Source string: 'SUSPEND_FROM_REDO'). To resume data movement on the database, you will need to resume the database manually. For information about how to resume an availability database, see SQL Server Books Online.</span></blockquote>
<h3>Resolve Secondary Replica Database Not Synchronizing</h3>
<strong>You cannot ONLINE a secondary replica availability group database </strong>Since a secondary replica availability group database is really in an ongoing restoring state, it cannot be set Online like the primary replica. Remember it is already in the Online role, according to the DMVs.

<strong>Solution</strong> Restart the SQL Server instance hosting the secondary replica. This will initiate recovery on all databases including availability group databases, and so long as SQL Server can access all the database files, the availability group database affected should recover successfully and resume synchronization with the primary replica.
<div style="width: 1000px;overflow: hidden">
<div></div>
</div>]]></content:encoded>
    </item>
    <item>
      <title>Avoid Availability Group Database Data Loss: Do not Deploy File Share Witness From DFS Namespace</title>
      <link>https://docs.microsoft.com/archive/blogs/alwaysonpro/avoid-availability-group-database-data-loss-do-not-deploy-file-share-witness-from-dfs-namespace</link>
      <pubDate>Tue, 29 Aug 2017 14:07:50 GMT</pubDate>
      <dc:creator><![CDATA[AlwaysOn Professionals]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alwaysonpro/?p=3485</guid>
      <description><![CDATA[Cluster Quorum File Share Witness Should Not be Part of a DFS Namespace
When deploying AlwaysOn...]]></description>
      <content:encoded><![CDATA[<h2>Cluster Quorum File Share Witness Should Not be Part of a DFS Namespace</h2>
When deploying AlwaysOn availability groups you may decide to add a vote to Windows Cluster quorum by configuring a File Share Witness. A requirement when configuring that File Share Witness is that it is not part of a Distributed File System (DFS) namespace. Adding a file share witness which is part of a DFS can result in split brain and ultimately data loss. It is documented in the section ‘Requirements and recommendations for clusters using Node and File Share Majority’ of <a href="https://technet.microsoft.com/en-us/library/cc770620(v=ws.10).aspx">Failover Cluster Step-by-Step Guide: Configuring the Quorum in a Failover Cluster</a>
<ul>
 	<li>Do not use a file share that is part of a Distributed File System (DFS) Namespace.</li>
</ul>
<h3>Avoid Data Loss In Your Availability Group Databases</h3>
If a File Share Witness for your Windows Cluster is incorrectly configured as part of a DFS, in the event of a communication between Windows Cluster nodes hosting availability group replicas, quorum may be arbitrated independently, resulting in split brain condition in the Windows Cluster.

The result is two or more availability group replicas will have independent views of the availability group state and may attain the primary role simultaneously, or automatic failover can occur to an availability replica that is not in a truly synchronized state. These are states and behaviors that can lead to the loss of data in your availability group databases.

Microsoft SQL Server support has worked with several customers who have experienced data loss due to split brain or the automatic failover of availability groups that were not synchronized as a result of this configuration.]]></content:encoded>
    </item>
    <item>
      <title>Troubleshooting Internal Load Balancer Listener Connectivity in Azure</title>
      <link>https://docs.microsoft.com/archive/blogs/alwaysonpro/troubleshooting-internal-load-balancer-listener-connectivity-in-azure</link>
      <pubDate>Wed, 22 Feb 2017 17:29:55 GMT</pubDate>
      <dc:creator><![CDATA[AlwaysOn Professionals]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alwaysonpro/?p=3325</guid>
      <description><![CDATA[Problem Unable to Connect to Azure availability group listener Creating an availability group in...]]></description>
      <content:encoded><![CDATA[<h3>Problem Unable to Connect to Azure availability group listener</h3> <p>Creating an availability group in order to make your application highly available when running on Azure virtual machines (IaaS) is very popular. The availability group listener requires special configuration steps in Azure as opposed to running on premise.&nbsp; <p>For more information on step by step configuration of Azure availability group listener, see the following article for Azure resource managed availability group.  <blockquote> <p><a href="https://docs.microsoft.com/en-us/azure/virtual-machines/windows/sql/virtual-machines-windows-portal-sql-alwayson-int-listener">Configure an internal load balancer for an Always On availability group in Azure</a></p></blockquote> <p>The following article will assist in troubleshooting the failure to connect to the availability group listener.  <p><strong>NOTE</strong> This troubleshooter focuses on an availability group listener configured with resource managed internal load balancer, which is the most popular type of listener currently deployed.  <h4>&nbsp;</h4> <h4>Testing the Azure availability group listener </h4> <p>To test an Azure availability group listener, do not test the listener connectivity on the primary replica. Instead, test listener connectivity to the primary replica using the listener, from the secondary replica. We know the secondary replica already has certain connectivity with the primary and that there are SQL Server client tools installed on it, that can be used for testing connectivity to the listener. Use a tool like sqlcmd for connectivity testing.  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/02/image463.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/02/image_thumb413.png" width="920" height="562"></a>  <p>&nbsp; <h3>Troubleshooting Failed Azure listener connectivity </h3> <p>Familiarizing yourself with the <a href="https://docs.microsoft.com/en-us/azure/virtual-machines/windows/sql/virtual-machines-windows-portal-sql-alwayson-int-listener">article that steps through the Azure listener creation and configuration</a> will help you understand the major pieces of the Azure listener configuration that need to be investigated to determine root cause. The majority of all listener connection issues are a result of incorrect configuration of one of the following:  <ul> <li> <p>Firewall or network security group configuration </p> <li> <p>IP Clustered resource creation and configuration (See section of article 'Configure the cluster to use the load balancer IP address')</p> <li> <p>Internal load balancer creation and configuration (See section of article 'Create and configure the load balancer in the Azure portal)'</p></li></ul> <p>&nbsp; <h4>Turn off Windows Firewall on the server hosting the primary replica (Firewall and NSG configuration)</h4> <p>The simplest way to ensure Windows Firewall is not blocking connectivity to the listener is to turn off Windows Firewall on the Windows server hosting the primary replica of the availability group, that which you are trying to connect to with your listener connectivity test.  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/02/image457.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/02/image_thumb407.png" width="734" height="269"></a>  <p>&nbsp; <p>If you find that connectivity succeeds, turn Firewall back on, and be sure to allow inbound connection through ports 1433 (port SQL Server is listening on) and 59999 (probe port).  <p>&nbsp; <h4>Investigate Network Security Group (NSG) for rules that block probe port or SQL Server port connectivity (Firewall and NSG configuration)</h4> <p>It is possible that a network security group rule is preventing connectivity to the virtual machine. For example, the following network security group has an inbound rule allowing SQL connectivity but it is overruled by a rule whose priority value is lower.  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/02/image464.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/02/image_thumb414.png" width="890" height="247"></a></p> <p>&nbsp;</p> <p>For more information review the following section 'Configure a Network Security Group inbound rule for the VM' in this article:  <blockquote> <p><a href="https://docs.microsoft.com/en-us/azure/virtual-machines/windows/sql/virtual-machines-windows-portal-sql-alwayson-int-listener">Connect to a SQL Server Virtual Machine on Azure (Resource Manager)</a></p></blockquote> <p>&nbsp; <h4>Verify RHS.EXE is listening on probe port (59999) (IP Clustered Resource creation and configuration)</h4> <p>On the server hosting the primary replica, verify that RHS.EXE process is listening on the probe port you configured the internal load balancer with.  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/02/image459.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/02/image_thumb409.png" width="636" height="173"></a></p> <p>&nbsp; <p>View the output with notepad and search for a process listening on port 59999 (probe port):  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/02/image460.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/02/image_thumb410.png" width="696" height="388"></a></p> <p>&nbsp;</p> <p>Use Task Manager to verify that the process listening on 59999 is RHS.EXE. If some other process is already listening on port 59999, then it will be necessary to reconfigure both the IP resource's probe port and the internal load balancer probe port to a different value so there is not a conflict.</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2017/02/image461.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/02/image_thumb411.png" width="534" height="485"></a></p> <p>&nbsp;</p> <h4>Review the internal load balancer configuration (Load Balancer creation and configuration)</h4> <p>Using the <a href="https://docs.microsoft.com/en-us/azure/virtual-machines/windows/sql/virtual-machines-windows-portal-sql-alwayson-int-listener">article on creating the Azure availability group listener</a>, step through the configuration steps 1-4 listed below and use the Azure portal to visually verify the configuration of each step below is correct:  <ol> <li>Create the load balancer and configure the IP address  <li>Configure the backend pool  <li>Create a probe  <li>Set the load balancing rules</li></ol> <p>&nbsp; <p>If a visual of the internal load balancer checks out, you can use network tracing to verify that the load balancer is pinging the probe port on the server hosting the primary replica. On the server hosting the primary replica, run netsh from the command line for 30 seconds:  <blockquote> <p><font size="2" face="Courier New">netsh trace start capture=yes tracefile=d:\nettrace.etl maxsize=200 filemode=circular overwrite=yes report=no</font></p></blockquote> <p>To stop the trace run  <blockquote> <p><font size="2" face="Courier New">netsh trace stop</font></p></blockquote> <p>Open the .ETL file using a tool like Network Monitor and filter for probe port activity. <strong>No traffic</strong> on the probe port of the virtual machine hosting the primary replica indicates one of two possibilities:  <ol> <ol> <li>The internal load balancer is not configured correctly.  <li>There is a network security group, firewall or corporate polcy that is interfering with the probe port traffic.</li></ol></ol> <p>&nbsp;</p> <p>Here we can see that when we filter on port 59999 we see activity which indicates that the load balancer appears to be performing correctly.</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2017/02/image462.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/02/image_thumb412.png" width="807" height="428"></a></p>]]></content:encoded>
    </item>
    <item>
      <title>How to Apply Transaction Logs to Secondary When it is Far Behind</title>
      <link>https://docs.microsoft.com/archive/blogs/alwaysonpro/how-to-apply-transaction-logs-to-secondary-when-it-is-far-behind-2</link>
      <pubDate>Wed, 22 Feb 2017 13:02:00 GMT</pubDate>
      <dc:creator><![CDATA[AlwaysOn Professionals]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alwaysonpro/?p=3245</guid>
      <description><![CDATA[&nbsp; Problem Large Send Queue You discover that the log send queue for a given availability...]]></description>
      <content:encoded><![CDATA[<p>&nbsp;</p> <h2>Problem Large Send Queue</h2> <p>You discover that the log send queue for a given availability database has grown very large, which threatens your Recovery Point Objective (RPO) and the transaction log has grown very large on the primary replica, possibly threatening to fill the drive. The cause may have been for various reasons: you discover that the availability database synchronization was inadvertently suspended by an administrator, or even by the system and the problem was not identified until now. </p> <h4><font style="font-weight: bold"></font>&nbsp;</h4> <h4><font style="font-weight: bold">Scenario 1</font> The database is not large</h4> <p>If it is reasonable to re-initialize the secondary replica copy of the database using a backup and restore of the database whose log file has grown very large, then you can allow synchronization to proceed to drain the log send queue or if the size of the transaction log is much larger than the database itself, remove the database from the availability group, shrink the log file and add it back into the availability group, re-seeding your secondary replicas with the newly added database. </p> <ol> <li>In SQL Server Management Studio (SSMS) remove the database from the availability group on the primary replica.</li> <li>Put the database in simple recovery mode on the primary replica. This will allow you to shrink the log file.</li> <li>Shrink the log file down to a reasonable size. To shrink the log file, in SSMS’ Object Explorer right-click the database, choose Tasks and then Shrink and then Files. For File type choose Log and click OK.</li> <li>Once log file has ben shrunk, configure the database for full recovery mode and then right-click the availability group, choose Add Database and use the wizard to add the database back and re-initialize the secondary replica with it.</li></ol> <h4><font style="font-weight: bold"></font>&nbsp;</h4> <h4><font style="font-weight: bold">Scenario 2</font> The database is very large, making re-initialization prohibitive to the secondary replicas </h4> <p>If the data portion of the database is very large combined with the remoteness of one or more secondary's, it may not be reasonable to use Scenario 1. Another option is to apply the log backups onto the database at the secondary, to 'catch up' the database at the secondary. Following are the steps. </p> <p>&nbsp;&nbsp; 1. Determine the transaction logs that must be applied. Query the last_hardened_lsn for the database on the secondary. Connect to the secondary and run the following supplying the database name as the only predicate:</p> <blockquote> <p><font size="2" face="Courier New">select distinct dcs.database_name, ds.last_hardened_lsn from  </font></p> <p><font size="2" face="Courier New">sys.dm_hadr_database_replica_states ds join sys.dm_hadr_database_replica_cluster_states dcs </font></p> <p><font size="2" face="Courier New">on ds.group_database_id=dcs.group_database_id</font></p> <p><font size="2" face="Courier New">where dcs.database_name='AutoHa-sample'</font></p></blockquote> <p>You will get results like this.</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2017/02/image430.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/02/image_thumb380.png" width="856" height="189"></a></p> <p>&nbsp;</p> <p>&nbsp;&nbsp; 2. Query the log backups in MSDB to find what log backup the secondary LSN falls in the range of.</p> <blockquote> <p><font size="2" face="Courier New">select name, backup_set_id, backup_start_date, backup_finish_date, first_lsn, last_lsn from msdb..backupset </font></p> <p><font size="2" face="Courier New">where first_lsn&lt;'93000012832800001' and last_lsn&gt;'93000012832800001'</font></p></blockquote> <p>&nbsp;</p> <p>We see one row returned, we need to apply all logs starting with this log on the secondary replica:</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2017/02/image431.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/02/image_thumb381.png" width="869" height="195"></a></p> <p>&nbsp;</p> <p><strong>Alternative to find the first transaction log backup </strong>Query sys.dm_hadr_database_replica_states.last_hardened_time for the database (same query as above). Use File Explorer to view the transaction log backup files and order by modified date. Compare the last_hardened_time with the backup modified dates to determine what transaction log backup you should start with, selecting the transaction log backup whose modified date is just beyond the last_hardened_time. Query that transaction log to verify the last_hardened_time falls in that transaction log backup:</p> <blockquote> <p><font size="2" face="Courier New">restore headeronly from disk= N'f:\backups\AutoHa-sample_backup_2017_01_20_194401_3869314.bak’</font></p></blockquote> <p>&nbsp;&nbsp; 3. Take database out of the availability group on the secondary. Connect to the secondary replica and execute the following to take the database out of the secondary replica.</p> <blockquote> <p><font size="2" face="Courier New">alter database [AutoHa-sample] set hadr off </font></p></blockquote> <p>On the secondary the database will be in Restoring and ready to apply logs to.</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2017/02/image432.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/02/image_thumb382.png" width="398" height="421"></a></p> <p>&nbsp;</p> <p>&nbsp;&nbsp; 4. Apply transaction logs to database on the secondary replica Apply the transaction log backups. Here is a view of the log backup files.&nbsp; We identified the one called 'AutoHa-sample_backup_2017_01_20_194401_3869314' as containing our secondary database last_hardened_lsn. </p> <p><a href="https://msdnshared.blob.core.windows.net/media/2017/02/image433.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/02/image_thumb383.png" width="854" height="394"></a></p> <p>&nbsp;</p> <p>Begin restoring with that log being sure to restore with 'no recovery' all the transaction log backups. </p> <h5></h5> <blockquote> <p><font size="2">res</font><font size="2" face="Courier New">tore log [AutoHa-sample] from disk='\\sqlserver-0\Backups\AutoHa-sample_backup_2017_01_20_194401_3869314.trn' with norecovery<br>go<br>restore log [AutoHa-sample] from disk='\\sqlserver-0\Backups\AutoHa-sample_backup_2017_01_20_194500_8646900.trn' with norecovery<br>go<br>restore log [AutoHa-sample] from disk='\\sqlserver-0\Backups\AutoHa-sample_backup_2017_01_20_194600_9809513.trn' with norecovery<br>go<br>restore log [AutoHa-sample] from disk='\\sqlserver-0\Backups\AutoHa-sample_backup_2017_01_20_200000_6780254.trn' with norecovery<br>go</font></p><font face="Courier New"></font><font face="Courier New"></font><font face="Courier New"></font><font face="Courier New"></font><font face="Courier New"></font></blockquote> <p>&nbsp;</p> <p>&nbsp;&nbsp; 5. Add the database back into the availability group on the secondary and resume synchronization. Connect to the secondary replica and execute the following to add the database back into the availability group and resume sync.</p> <blockquote> <p><font size="2" face="Courier New">alter database [AutoHa-sample] set hadr availability group = [contoso-ag] <br>go <br>alter database [AutoHa-sample] set hadr resume <br>go </font></p></blockquote> <p><font size="2">You can view the availability group database on the secondary to confirm it is added back and synchronized.</font></p> <p><a href="https://msdnshared.blob.core.windows.net/media/2017/02/image434.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/02/image_thumb384.png" width="355" height="466"></a></p>]]></content:encoded>
    </item>
    <item>
      <title>Making Service Broker Application Highly Available With AlwaysOn</title>
      <link>https://docs.microsoft.com/archive/blogs/alwaysonpro/making-service-broker-application-highly-available-with-alwayson</link>
      <pubDate>Thu, 26 Jan 2017 21:16:05 GMT</pubDate>
      <dc:creator><![CDATA[AlwaysOn Professionals]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alwaysonpro/?p=3146</guid>
      <description><![CDATA[&nbsp;  If you have a Service Broker (SSB) application connecting to SQL Server using an AlwaysOn...]]></description>
      <content:encoded><![CDATA[<p>&nbsp; <p><b></b> <p>If you have a Service Broker (SSB) application connecting to SQL Server using an AlwaysOn availability group listener, in the event of an unexpected failover, some messages may be lost or stuck in the transmission queue on the old primary (new secondary) after the failover. This could be an automatic failover or manual failover when the SSB application is not stopped.  <p>Incoming (SSB) connections are severed during a availability group failover and those connections use the listener IP address which directs connections to the new primary replica. New incoming SSB connections, established through the listener, will go to the new replica. This is the correct and intended behavior. <p>&nbsp; <p><a href="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image00111.jpg"><img width="348" height="223" title="clip_image001" style="border-width: 0px;padding-top: 0px;padding-right: 0px;padding-left: 0px" alt="clip_image001" src="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image001_thumb9.jpg" border="0"></a>  <p>&nbsp; <p>The availability group fails over and the new inbound SSB connections reset to the new primary replica: <p>&nbsp; <p><a href="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image00230.jpg"><img width="350" height="233" title="clip_image002" style="border-width: 0px;padding-top: 0px;padding-right: 0px;padding-left: 0px" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image002_thumb26.jpg" border="0"></a>  <p>&nbsp; <p>However, outgoing SSB connections from the old primary replica are left open after a failover, still in session with the initiator, and remain so because the IP addresses are still valid. New outgoing SSB connections are established from the new replica to the initiator, but because the connections from the old primary are still open, incoming SSB messages are still sent to the old primary.  <p>Since Service Broker components are not contained within the availability group, special handling is required to handle the Service Broker connections when the availability group moves to a different replica instance. If you feel the post failover handling for the Service Broker connection is not feasible to be built into your application, please submit a Connect item (<a href="https://connect.microsoft.com/sql">https://connect.microsoft.com/sql</a>) so that we are able to understand the community need for this functionality. As an alternative to modifying the code for your application, you could choose to use a SQL Server Failover Cluster Instance which will prevent the issue described above, due to the IP Address remaining the same on failover. <p>&nbsp; <p><a href="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image0038.jpg"><img width="355" height="231" title="clip_image003" style="border-width: 0px;padding-top: 0px;padding-right: 0px;padding-left: 0px" alt="clip_image003" src="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image003_thumb8.jpg" border="0"></a>  <p>&nbsp; <h3></h3><h3><font color="#0000ff" style="font-weight: bold">UPDATE: Enhanced Compatibility When Hosting Service Broker in Availability Groups</font></h3><p>This behavior has been improved in the following versions of SQL Server:</p>
<blockquote><p>SQL 2014 SP1/CU12 &amp; SP2/CU5<br>
SQL 2016 RTM/CU6 &amp; SP1/CU3<br>
SQL 2012 SP4</p></blockquote>
<p>For more information on these improvements, see the following KnowledgeBase article:</p><blockquote><p><a href="https://support.microsoft.com/en-us/help/4016361/fix-service-broker-endpoint-connections-aren-t-closed-after-an-availab">FIX: Service Broker endpoint connections aren't closed after an availability group failover in SQL Server</a><br>
</p></blockquote>
<p><b></b> <h3>Troubleshooting</h3> <p>If, after the failover, you run the following query on the old primary SSB TARGET and see the value for <b>is_accepted = 0</b> then you know you have encountered the issue. You will also likely have two or more connections returned here.&nbsp; <p><br><blockquote> <h5><font face="Courier New">--look for is_accept = 0</font></h5> <h5><font face="Courier New">select is_accept, * from sys.dm_broker_connections with(nolock)</font></h5></blockquote> <p><b></b> <p>&nbsp; <p>Another side effect are messages stuck in the <b>sys.transmission_queue</b> on the old primary SSB TARGET. <p>If Profiler trace is run on the old primary SSB TARGET, you would see the following error: <p>&nbsp; <blockquote> <h5><font face="Courier New">The message has been dropped because the service broker in the target database is unavailable: <font color="#ff0000">‘The database is in read-only mode.’</font></font></h5></blockquote> <p><br></p> <p><a href="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image002110.jpg"><img width="1036" height="387" title="clip_image002[1]" style="border: 0px currentcolor;padding-top: 0px;padding-right: 0px;padding-left: 0px" alt="clip_image002[1]" src="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image0021_thumb.jpg" border="0"></a></p> <p>&nbsp; </p> <p>SQL Server XEvent ‘broker_message_undeliverable’ can also be collected using SQL Server extended events and will also report that messages cannot be delivered. For more information on using SQL Server extended events, see:</p> <blockquote> <h5><a href="https://technet.microsoft.com/en-us/library/gg471585(v=sql.120).aspx">Create an Extended Events Session Using the Wizard (Object Explorer)</a></h5></blockquote> <p><br></p> <h3>Workaround</h3> <p>Host the primary replica on a SQL Failover Cluster Instance (SQL FCI). In the event of a failover, SQL Server restarts and the initiator will re-establish connectivity with the availability group listener and the TARGET will re-establish connections with the initiator. There will be no residual broker connections or in-flight transactions that cannot be resolved. <p>In this scenario, you still have a secondary replica hosted on a standalone instance of SQL Server which provides another means of high availability. <p>&nbsp; <p><a href="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image00414.jpg"><img width="374" height="257" title="clip_image004" style="border-width: 0px;padding-top: 0px;padding-right: 0px;padding-left: 0px" alt="clip_image004" src="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image004_thumb10.jpg" border="0"></a>  <p>&nbsp; <h3>Maintenance</h3> <p>When failing manually over between availability group replicas for rolling upgrade purposes, stop the Service Broker Application before doing the manual availability group failover to prevent any in-flight transactions from getting stuck.]]></content:encoded>
    </item>
    <item>
      <title>AlwaysOn Readable Secondaries Can Display Misleading Data &amp; Log File Paths</title>
      <link>https://docs.microsoft.com/archive/blogs/alwaysonpro/alwayson-readable-secondaries-can-display-misleading-data-log-file-paths</link>
      <pubDate>Wed, 29 Jun 2016 21:07:05 GMT</pubDate>
      <dc:creator><![CDATA[AlwaysOn Professionals]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alwaysonpro/?p=3025</guid>
      <description><![CDATA[Written By:

Grant Carter, Senior Premier Field Engineer

Reviewed By:

Mark Weber – Principal...]]></description>
      <content:encoded><![CDATA[<strong>Written By:</strong>

Grant Carter, Senior Premier Field Engineer

<strong>Reviewed By:</strong>

Mark Weber – Principal Premier Field Engineer

Norm Eberly – Senior Premier Field Engineer

Charles Allard – Senior Premier Field Engineer

Nick Schueler - Senior Premier Field Engineer

Curt Matthews – Senior Escalation Engineer

&nbsp;

<strong>Problem</strong>

You may discover on a readable secondary database that is part of an AlwaysOn Availability Group the data and transaction log file locations in sp_helpdb and sys.databases_files may display inaccurate results.

&nbsp;

<strong>Scenario</strong>

Results from these DMVs and stored procedures may be unexpected when executing them against the readable secondary if the readable secondary was restored with the move option and placed on a different file path as compared to the file path of the primary replica.   For example, the primary replica may have its files on the E: drive and the secondary replica may have its files on the L: drive. In the example below, you will see that the database is on the E: drive, but it was manually restored using the move command to the L: drive.

<em>On the primary replica:</em>
<pre>create database [ag1db1]
on
(
       name = 'ag1db1_data'
       , filename = 'E:\SQL\ag1db1_data.mdf'
       , size = 20MB
       , maxsize = 20MB
       , filegrowth = 0
)
log on
(
       name = 'ag1db1_log'
       , filename = 'E:\SQL\ag1db1_log.ldf'
       , size = 20MB
       , maxsize = 20MB
       , filegrowth = 0
)
go</pre>
<em>On the secondary replica:</em>
<pre>restore database [ag1db1] from disk = '\\sql2014n1\Backup\ag1db1.bak'
with
       move 'ag1db1_data' to 'L:\SQL\ag1db1_data.mdf'
       , move 'ag1db1_log' to 'L:\SQL\ag1db1_log.ldf'
       , norecovery
       , stats=10
go</pre>
&nbsp;

Based on the script above, you can see that the data and log paths are different between the primary and readable secondary replica. The primary files were place on the E:\SQL directory and the readable secondary files were placed on the L:\SQL directory.  On the readable secondary replica, the sp_helpdb command returns a file path that is the same as the primary replica and not on the L: drive as the database restore command specified using the move option.
<pre>sp_helpdb ag1db1
go</pre>
<table style="height: 239px" width="813">
<tbody>
<tr>
<td width="93"><strong>name</strong></td>
<td width="47"><strong>fileid</strong></td>
<td width="168"><strong>filename</strong></td>
<td width="71"><strong>filegroup</strong></td>
<td width="76"><strong>size</strong></td>
<td width="69"><strong>maxsize</strong></td>
<td width="58"><strong>growth</strong></td>
<td width="78"><strong>usage</strong></td>
</tr>
<tr>
<td width="93">ag1db1_data</td>
<td width="47">1</td>
<td width="168">E:\SQL\ag1db1_data.mdf</td>
<td width="71">PRIMARY</td>
<td width="76">20480 KB</td>
<td width="69">20480 KB</td>
<td width="58">0 KB</td>
<td width="78">data only</td>
</tr>
<tr>
<td width="93">ag1db1_log</td>
<td width="47">2</td>
<td width="168">E:\SQL\ag1db1_log.ldf</td>
<td width="71">NULL</td>
<td width="76">20480 KB</td>
<td width="69">20480 KB</td>
<td width="58">0 KB</td>
<td width="78">log only</td>
</tr>
</tbody>
</table>
&nbsp;

If sys.databases on the secondary replica is queried, the result will show the data and log files on the E: drive just as they did with sp_helpdb on the readable secondary replica which is different than the path they were restored to.
<pre>use ag1db1
go
select name, physical_name
from sys.database_files
go</pre>
<table width="248">
<tbody>
<tr>
<td width="85"><strong>name</strong></td>
<td width="163"><strong>physical_name</strong></td>
</tr>
<tr>
<td width="85">ag1db1_data</td>
<td width="163">E:\SQL\ag1db1_data.mdf</td>
</tr>
<tr>
<td width="85">ag1db1_log</td>
<td width="163">E:\SQL\ag1db1_log.ldf</td>
</tr>
</tbody>
</table>
&nbsp;

The sys.master_files view will report accurate details about database file locations at the readable secondary replica. Unlike sp_helpdb and sys.databases_files, the sys.master_files view reflects the actual paths specified in the restore with move command as opposed to the file paths for the primary replica.
<pre>use master
go
select name, physical_name
from sys.master_files where database_id = db_id('ag1db1')
go</pre>
<table width="248">
<tbody>
<tr>
<td width="85"><strong>name</strong></td>
<td width="163"><strong>physical_name</strong></td>
</tr>
<tr>
<td width="85">ag1db1_data</td>
<td width="163">L:\SQL\ag1db1_data.mdf</td>
</tr>
<tr>
<td width="85">ag1db1_log</td>
<td width="163">L:\SQL\ag1db1_log.ldf</td>
</tr>
</tbody>
</table>
&nbsp;

<strong>Reason for Behavior</strong>

sp_helpdb calls a stored procedure called sp_helpfile. sp_helpfile is a stored procedure that queries a view called sys.sysfiles.   sys.sysfiles gets its data from a system table called sys.sysprufiles. sys.syspruefiles is scoped at the database level. Because the secondary is a mirrored copy of the primary, the data in sys.sysprufiles reflects as it would on the primary, not the secondary, because of its scope. For this reason, the data on a readable secondary will always match the data on the primary replica.

If the availability group were to be failed over and the new readable secondary queried, it would be updated to appear as if its files were on the L: drive to reflect the new primary.

sys.database_files is a view that also uses sys.sysprufiles as its base data. Because of that, the behavior is the same as it is for sp_helpdb or sp_helpfile.

sys.master_files is a view that is scoped at the master database level that calls a system table called sys.sysbrickfiles. The metadata is maintained at the master database level and isn’t mirrored between the replicas like the database scoped system tables. For this reason, sys.master_files demonstrates the correct location of the data and log files for the database on that replica regardless of which replica is primary and which is secondary.

It is important to remember that in order to get the correct locations of where the data and transaction log files are located on a readable secondary replica, sys.master_files will give you the correct location. Relying on sys.database_files or sp_helpdb will give you an inaccurate result if the file locations between the primary and secondary replica are different.]]></content:encoded>
    </item>
    <item>
      <title>SQL Server 2016 AlwaysOn Availability Group Enhancements: Support for Encrypted Databases</title>
      <link>https://docs.microsoft.com/archive/blogs/alwaysonpro/sql-server-2016-alwayson-availability-group-enhancements-support-for-encrypted-databases</link>
      <pubDate>Thu, 23 Jun 2016 14:49:33 GMT</pubDate>
      <dc:creator><![CDATA[AlwaysOn Professionals]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alwaysonpro/?p=3015</guid>
      <description><![CDATA[Overview
In SQL Server 2012 and SQL Server 2014, encrypted databases could be added to an AlwaysOn...]]></description>
      <content:encoded><![CDATA[<h3>Overview</h3>
In SQL Server 2012 and SQL Server 2014, encrypted databases could be added to an AlwaysOn availability group, but they could not be added using the New Availability Group wizard. Additionally, in the event of a failover, the encrypted database data could not be accessed. This is because the database master key in the availability group database was not compatible with the service master key on the other SQL Server instances hosting replicas for that availability group.

For more information on how to add encrypted databases to an availability group and make those databases highly available on all replicas in SQL Server 2012 or SQL Server 2014, see the AlwaysOnPro blog:
<blockquote><a href="https://blogs.msdn.microsoft.com/alwaysonpro/2014/01/28/how-to-enable-tde-encryption-on-a-database-in-an-availability-group/">How to enable TDE Encryption on a database in an Availability Group</a></blockquote>
SQL Server 2016 adds support to the availability group wizard for adding encrypted databases and simplifies database access following availability group failover.

<strong>NOTE</strong> This improvement is part of support for adding the SQL Server Integration Services database (SSISDB) to an AlwaysOn availability group for high availability. For more information see
<blockquote><a href="https://msdn.microsoft.com/en-us/library/mt163864.aspx">Always On for SSIS Catalog (SSISDB)</a></blockquote>
<h4>New Availability Group Wizard Adds Support for Encrypted Database</h4>
In SQL Server 2016, if you select an encrypted database for inclusion in an availability group, the New Availability Group wizard detects that the database is defined with a database master key and prompts the administrator for the database master key password.

<a href="https://msdnshared.blob.core.windows.net/media/2016/06/EncryptAGwizard.png"><img style="border-width: 0px" title="EncryptAGwizard" src="https://msdnshared.blob.core.windows.net/media/2016/06/EncryptAGwizard_thumb.png" alt="EncryptAGwizard" width="417" height="386" border="0" /></a>     <a href="https://msdnshared.blob.core.windows.net/media/2016/06/EncryptAGwizard1.png"><img style="border-width: 0px" title="EncryptAGwizard1" src="https://msdnshared.blob.core.windows.net/media/2016/06/EncryptAGwizard1_thumb.png" alt="EncryptAGwizard1" width="417" height="388" border="0" /></a>

After adding the database with a database master key, the wizard will verify the password during validation. When clicking Finish, credentials are created on each replica using the password of the database master key.

<a href="https://msdnshared.blob.core.windows.net/media/2016/06/EncryptAGwizardValidate.png"><img style="border-width: 0px" title="EncryptAGwizardValidate" src="https://msdnshared.blob.core.windows.net/media/2016/06/EncryptAGwizardValidate_thumb.png" alt="EncryptAGwizardValidate" width="414" height="387" border="0" /></a>     <a href="https://msdnshared.blob.core.windows.net/media/2016/06/EncryptAGwizardCred.png"><img style="border-width: 0px" title="EncryptAGwizardCred" src="https://msdnshared.blob.core.windows.net/media/2016/06/EncryptAGwizardCred_thumb.png" alt="EncryptAGwizardCred" width="413" height="384" border="0" /></a>
<h4></h4>
<h4>Added Support for Accessing Encrypted Availability Group Database After Failover</h4>
On creation, a database's database master key is encrypted using the SQL Server service master key, which is unique to that SQL Server instance. When a database defined with a database master key is added to an availability group, upon failover to another replica, decryption is not possible for that database when brought online in the primary role on a different SQL Server instance with an incompatible service master key.

When SQL Server needs a database master key to decrypt or encrypt a key, SQL Server tries to decrypt the database master key with the service master key of the instance. If the decryption fails (which in the case following failover, would occur), SQL Server searches the credential store for master key credentials that have the same family GUID as the database for which it needs the master key. SQL Server then tries to decrypt the database master key with each matching credential until the decryption succeeds or there are no more credentials.

Beginning in SQL Server 2016, when you create an availability group containing an database containing a database master key, the New Availability Group Wizard executes procedure <em>sp_control_dbmasterkey_password</em> against each replica to create these credentials associated with the database master key.
<blockquote>EXEC sp_control_dbmasterkey_password @db_name = @dbName, @password = @pwd, @action = N''add''',N'@dbName nvarchar(9),@password nvarchar(20)',@dbName=N'encryptDB',@password=N'1a2b3c4d5e6f7g8h9i0!'</blockquote>
In the event that this replica becomes the primary, and the database master key must be decrypted, SQL Server will first attempt to decrypt the key with the SQL Server instance service master key which will fail. Next, SQL Server will search for and find these credentials that can decrypt the database master key.

You can view the new credentials by querying sys.credentials and sys.master_key_passwords.

<a href="https://msdnshared.blob.core.windows.net/media/2016/06/EncryptCredDBMastKey.png"><img style="border-width: 0px" title="EncryptCredDBMastKey" src="https://msdnshared.blob.core.windows.net/media/2016/06/EncryptCredDBMastKey_thumb.png" alt="EncryptCredDBMastKey" width="862" height="147" border="0" /></a>
<h4>More Information About the Relationship between the SQL Server service master key and the database master key</h4>
SQL Server has two primary applications for keys: a service master key (SMK) generated on and for a SQL Server instance, and a database master key (DMK) used for a database. The SMK is automatically generated the first time the SQL Server instance is started and is used to encrypt a linked server password, credentials, and the database master key. The database master key is a symmetric key that is used to protect the private keys of certificates and asymmetric keys that are present in the database.

The database master key is a symmetric key used to protect the private keys of certificates and asymmetric keys that are present in the database.  To enable the automatic decryption of the master key, a copy of the key is encrypted by using the service master key and stored in both the database and in master. Typically, the copy stored in master is silently updated whenever the master key is changed.
<h5>Database Master Key credentials</h5>
When SQL Server needs a database master key to decrypt or encrypt a key, SQL Server tries to decrypt the database master key with the service master key of the instance. If the decryption fails, SQL Server searches the credential store for master key credentials that have the same family GUID as the database for which it needs the master key. SQL Server then tries to decrypt the database master key with each matching credential until the decryption succeeds or there are no more credentials.

In prior versions of SQL Server, if a database contain some encrypted columns protected by database master key and the database is added into an AlwaysOn availability group, the database in the new primary node cannot decrypt the database master key automatically after failover. In order to encrypt/decrypt data on the new primary node, you have to use OPEN MASTER KEY statement explicitly to open the database master key.

<a href="https://msdnshared.blob.core.windows.net/media/2016/06/clip_image00219.png"><img style="border-width: 0px" title="clip_image002" src="https://msdnshared.blob.core.windows.net/media/2016/06/clip_image002_thumb10.png" alt="clip_image002" width="397" height="274" border="0" /></a>

As the above picture show, When the database master key is created, the master key is encrypted by using the AES_256 algorithm and a user-supplied password. To enable the automatic decryption of the database master key, a copy of the key is encrypted by using the Service Master Key (SMK) and stored in both the database and in master database.

Since the Service Master Key is generated for a SQL Server instance, SQL Server Instance A and SQL Server Instance B have different service master key.

When failover occurs with the database, the secondary node (Node 2) became the primary node of the availability group, but the copy of database master key in Node 2’s database is encrypted by Service Key A instead of Service Key B. Thus after failover, the database in SQL Server Instance B cannot decrypt the database master key automatically.
<h3>For more information see the following resources:</h3>
<blockquote>For more information, please see
<blockquote><a href="https://msdn.microsoft.com/en-us/library/bb510663.aspx">SQL Server Encryption</a>

<a href="https://msdn.microsoft.com/en-us/library/bb964742.aspx.">SQL Server and Database Encryption Keys (Database Engine)</a>

<a href="https://msdn.microsoft.com/en-us/library/ms174382.aspx">CREATE MASTER KEY (Transact-SQL)</a>

<a href="https://blogs.msdn.microsoft.com/alwaysonpro/2014/01/28/how-to-enable-tde-encryption-on-a-database-in-an-availability-group/">How to enable TDE Encryption on a database in an Availability Group</a>

<a href="https://msdn.microsoft.com/en-us/library/ms182754.aspx">sp_control_dbmasterkey_password (Transact-SQL)</a></blockquote>
</blockquote>]]></content:encoded>
    </item>
    <item>
      <title>SQL Server 2016 AlwaysOn Availability Group Enhancements: Multiple Automatic Failover Targets</title>
      <link>https://docs.microsoft.com/archive/blogs/alwaysonpro/sql-server-2016-alwayson-availability-group-enhancements-multiple-automatic-failover-targets</link>
      <pubDate>Mon, 02 May 2016 16:10:25 GMT</pubDate>
      <dc:creator><![CDATA[AlwaysOn Professionals]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alwaysonpro/?p=2605</guid>
      <description><![CDATA[Overview
SQL Server 2104 and SQL Server 2012 can have two synchronous secondary replicas. One...]]></description>
      <content:encoded><![CDATA[<h3>Overview</h3>
SQL Server 2104 and SQL Server 2012 can have two synchronous secondary replicas. One synchronous secondary replica can serve the role as automatic failover partner with the primary replica.

In SQL Server 2016 both synchronous secondary replicas can be configured as automatic failover partners with the primary replica.
<h3>Benefits</h3>
This will allow following benefits
<ul>
	<li>This increases the chances that high availability can be maintained if one of the automatic failover partners is lost.</li>
	<li>Reduces the need to manually manage failovers or to reconfigure the availability group with another automatic failover partner in the event that one of the automatic failover partners is unavailable.</li>
</ul>
<h3>Configure Multiple Automatic Failover Targets</h3>
You can configure three replicas as automatic failover partners using Transact-SQL or SQL Server Management Studio.
<table border="0" width="766" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="241">
<blockquote>&nbsp;

<span style="font-size: small">USE [master]
GO </span>

<span style="font-size: small">ALTER AVAILABILITY GROUP [AG]
MODIFY REPLICA ON N'<strong>SQLN1</strong>' WITH (<strong>FAILOVER_MODE = AUTOMATIC</strong>)
GO </span>

<span style="font-size: small">ALTER AVAILABILITY GROUP [AG]
MODIFY REPLICA ON N'<strong>SQLN2</strong>' WITH (<strong>FAILOVER_MODE = AUTOMATIC</strong>)
GO </span>

<span style="font-size: small">ALTER AVAILABILITY GROUP [AG]
MODIFY REPLICA ON N'<strong>SQLN3</strong>' WITH (<strong>FAILOVER_MODE = AUTOMATIC</strong>)
GO </span></blockquote>
</td>
<td valign="top" width="523"><a href="https://msdnshared.blob.core.windows.net/media/2016/05/image78.png"><img style="border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/05/image_thumb75.png" alt="image" width="508" height="417" border="0" /></a></td>
</tr>
</tbody>
</table>
<h3></h3>
<h3>Troubleshooting Automatic Failover Problems</h3>
Troubleshooting multiple automatic failover targets would be similar to the steps of the following article used to troubleshoot automatic failover issues with a single automatic failover target:
<blockquote><a href="https://support.microsoft.com/en-us/kb/2833707">Troubleshooting automatic failover problems in SQL Server 2012 AlwaysOn environments </a></blockquote>
<strong>Useful Query</strong>

The following query may be used to check replica properties for multiple automatic failover partners and AG database synchronization health:
<blockquote><span style="font-family: Courier New;font-size: small">select replica_server_name, availability_mode_desc,failover_mode_desc, database_id, synchronization_health_desc,synchronization_state_desc,* from sys.availability_replicas as AR inner join sys.dm_hadr_database_replica_states as DRS on DRS.replica_id = AR.replica_id</span></blockquote>
<a href="https://msdnshared.blob.core.windows.net/media/2016/05/image79.png"><img style="border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/05/image_thumb76.png" alt="image" width="792" height="109" border="0" /></a>
<h3></h3>
<h3>FAQs</h3>
<strong>If both the secondary replicas are SYNCHRONIZED and healthy, which replica with Cluster choose to failover to? </strong>

<span style="font-size: small">Windows Cluster will attempt to failover to the next replica in the preferred owner list of the availability group, which dictates attempted failover order. The preferred owner list of the availability group role in Cluster will list all the availability group replicas defined for automatic failover.</span>

<span style="font-size: small">For example replicas SQL16N1 (primary), SQL16N2 (secondary) and SQL16N3 (secondary replica) are all defined for automatic failover and are in that order in the preferred owner list. In the event that a health issue is detected in SQL16N1, Cluster will attempt to failover to SQL16N2 next. In the event that SQL16N2 is not healthy (for example, an availability database was not SYNCHRONIZED) Cluster will attempt to failover to SQL16N3.</span>

<span style="font-size: small">Here is a picture of the availability group role properties from Failover Cluster Manager, note the Up and Down buttons for setting priority of these nodes as owner of the primary replica.</span>
<blockquote><a href="https://msdnshared.blob.core.windows.net/media/2016/05/image80.png"><img style="float: none;margin-left: auto;margin-right: auto;border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/05/image_thumb77.png" alt="image" width="379" height="452" border="0" /></a></blockquote>
<strong><em>Can we set the automatic failover priority, choosing a particular replica for a preferred failover target in SQL Server or by using Failover Cluster Manager? </em></strong>

<span style="font-size: small">There is no setting in SQL Server for configuring the preferred owner list settings of the availability group role. In addition, resetting the priority of the nodes in the preferred owner list of the availability group role in Failover Cluster Manager is also not recommended because </span><a href="https://blogs.msdn.com/b/alwaysonpro/archive/2014/02/28/sql-availability-group-ag-resource-and-possible-owners-and-preferred-owners.aspx"><span style="font-size: small">SQL Server manages Preferred and Possible Owner Properties for AlwaysOn Availability Group/Role</span></a><span style="font-size: small">. When a failover occurs, SQL Server resets the Preferred Owner list, over-writing any change made through Failover Cluster Manager.</span>

<span style="font-size: small">Furthermore, modifying AG resource properties in the </span><a href="https://msdn.microsoft.com/en-us/library/ff878487.aspx#RestrictionsAG"><span style="font-size: small">cluster manager is not recommended</span></a><span style="font-size: small">.</span>

<span style="font-size: small">Tests have shown you can change the Preferred Owner list in Failover Cluster, and the next automatic failover will abide by the modified preferred owner list. However, once SQL Server resets the preferred owner list, subsequent automatic failovers will proceed with the preferred owner priority set by SQL Server.</span>
<h4></h4>
<strong>Workaround: Configure automatic failover priority by adding replicas to availability group in preferred automatic failover priority</strong>

SQL Server will set the preferred owner list priority based on the order in which your availability group replicas are added to the availability group. This can allow you some control over what automatic failover partner Cluster attempts to failover to first.

For example, you have defined an availability group with primary replica SQL16N1 and add SQL16N2 and SQL16N3 as automatic failover partners. If you add SQL16N2 and then SQL16N3 using the Add Replica to Availability Group wizard, SQL Server will add them in the same order to the preferred owner list:
<table border="0" width="400" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="200"><a href="https://msdnshared.blob.core.windows.net/media/2016/05/image81.png">
<img style="border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/05/image_thumb78.png" alt="image" width="360" height="336" border="0" /></a></td>
<td valign="top" width="200"><a href="https://msdnshared.blob.core.windows.net/media/2016/05/image82.png"><img style="border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/05/image_thumb79.png" alt="image" width="319" height="380" border="0" /></a></td>
</tr>
</tbody>
</table>
<p align="left">When a health event is detected in SQL16N1 (in this example, I shut down SQL16N1 through SSMS Object Explorer), Cluster checks the next node in the preferred owner list which is SQL16N2. Assuming it is healthy and SYNCHRONIZED, Cluster will successfully failover to SQL16N2.</p>
<p align="left"><a href="https://msdnshared.blob.core.windows.net/media/2016/05/image83.png"><img style="float: none;margin-left: auto;margin-right: auto;border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/05/image_thumb80.png" alt="image" width="214" height="494" border="0" /></a></p>
<p align="left">Now, try adding the availability replicas in the reverse order to the availability group, like this. After adding the replicas, check the properties of the availability group role to confirm the order of the preferred owner list:</p>

<table border="0" width="400" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="200"><a href="https://msdnshared.blob.core.windows.net/media/2016/05/image84.png">
<img style="border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/05/image_thumb81.png" alt="image" width="378" height="352" border="0" /></a></td>
<td valign="top" width="200"><a href="https://msdnshared.blob.core.windows.net/media/2016/05/image85.png"><img style="border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/05/image_thumb82.png" alt="image" width="333" height="399" border="0" /></a></td>
</tr>
</tbody>
</table>
<p align="left">When a health issue is detected on SQL16N1 (again shut down SQL Server on SQL16N1) we can see the preferred owner list priority is honored and Cluster attempts to failover to SQL16N3 first and successfully.</p>
&nbsp;

<a href="https://msdnshared.blob.core.windows.net/media/2016/05/image86.png"><img style="float: none;margin-left: auto;margin-right: auto;border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/05/image_thumb83.png" alt="image" width="235" height="540" border="0" /></a>
<h3>For more information see the following link on automatic failover:</h3>
<blockquote>
<p align="left"><a href="https://msdn.microsoft.com/en-us/library/hh213151.aspx">Failover and Failover Modes (Always On Availability Groups)</a></p>
</blockquote>]]></content:encoded>
    </item>
  </channel>
</rss>