<?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>Pieter Vanhove</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/msftpietervanhove/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/msftpietervanhove/feed.xml</link>
    <description>My Microsoft SQL Blog</description>
    <lastBuildDate>Thu, 14 Dec 2017 11:10:23 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Top 7 Questions about Basic Availability Groups</title>
      <link>https://docs.microsoft.com/archive/blogs/msftpietervanhove/top-5-questions-about-basic-availability-groups</link>
      <pubDate>Tue, 14 Mar 2017 22:26:31 GMT</pubDate>
      <dc:creator><![CDATA[Pieter Vanhove]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/msftpietervanhove/?p=865</guid>
      <description><![CDATA[AlwaysOn Basic Availability Groups provide a “basic” high availability solution for SQL Server 2016...]]></description>
      <content:encoded><![CDATA[<span style="font-size: small">AlwaysOn Basic Availability Groups provide a “basic” high availability solution for SQL Server 2016 Standard Edition. The functionality is the same as the traditional (Enterprise Edition) AlwaysOn Availability Groups but there are more limitations:</span>

<span style="font-size: small">The most important limitations are:</span>
<ul>
 	<li><span style="font-size: small">Limit of two replicas (primary and secondary)</span></li>
 	<li><span style="font-size: small">No read access on secondary replica</span></li>
 	<li><span style="font-size: small">One database per group</span></li>
</ul>
<span style="font-size: small"></span>

<span style="font-size: small">More detailed information can be found <a target="_blank" href="https://msdn.microsoft.com/en-us/library/mt614935.aspx" rel="noopener">here.</a></span>

<span style="font-size: small">I received a lot a questions of customers and on <a target="_blank" href="https://blogs.technet.microsoft.com/msftpietervanhove/2016/05/10/how-to-set-up-basic-availability-groups-in-sql-server-2016/" rel="noopener">my previous blog post</a> about those limitations and possible configurations; s</span><span style="font-size: small">o I wanted to share the top 5 questions in this blog post.</span>
<h2>1. Can I create more than 1 availability group?</h2>
<span style="font-size: small">Yes, you can create more than 1 availability group with SQL Server 2016 Standard Edition. Each group that you create can only contain 1 database. As you can see in the screenshot below, I’ve created as an example 3 availability groups. Each group contains 1 database and I’ve configured for each group a different group listener.</span>

&nbsp;

<span style="font-size: small"></span>

<a href="https://msdnshared.blob.core.windows.net/media/2017/03/image342.png"><img width="339" height="469" title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/03/image_thumb334.png" border="0" /></a>

&nbsp;
<h2></h2>
<h2></h2>
<h2></h2>
<h2>2. Can I use automatic failover?</h2>
<span style="font-size: small">This is not mentioned in the <a target="_blank" href="https://msdn.microsoft.com/en-us/library/mt614935.aspx#Limitations" rel="noopener">limitations</a> which means automatic failover is supported.</span>

<span style="font-size: small">As you can see in the screenshot below, I’ve configured my availability group with Synchronous commit mode and Failover Mode to Automatic. You can also use Asynchronous commit mode, which is different compared to database mirroring. Of course, asynchronous commit mode doesn’t allow automatic failover.</span>

&nbsp;

<a href="https://msdnshared.blob.core.windows.net/media/2017/03/image343.png"><img width="1150" height="812" title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/03/image_thumb335.png" border="0" /></a>

&nbsp;
<h2>3. Can I configure more than 2 replicas?</h2>
<span style="font-size: small">No, you cannot configure more than 2 replicas per availability group. But that doesn’t mean you can’t configure more instances as a replica in different groups. Make sure that the replicas are all part of the same Windows Failover Cluster. As an example, I’ve made a configuration with 3 instances.</span>

&nbsp;

<a href="https://msdnshared.blob.core.windows.net/media/2017/03/image344.png"><img width="406" height="462" title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/03/image_thumb336.png" border="0" /></a>

<span style="font-size: small">Node1 is primary replica for BASIC_AG1 and BASIC_AG3 and it’s secondary replica for BASIC_AG2.</span>

<span style="font-size: small">Node 2 is currently not configured as a primary but only as secondary for BASIC_AG1 and BASIC_AG3.</span>

<span style="font-size: small">Node 3 is primary replica for BASIC_AG2 and is currently not configured as secondary replica.</span>

<span style="font-size: small">As you can see, multiple configurations are possible. But please do keep in mind that technically, you can create these kind of configurations but it will be a nightmare to administer… If it is truly a critical application, I would question how critical it is to not receive the other Enterprise Edition benefits.</span>
<h2>4. Does a Basic Availability Group support databases with FILESTREAM?</h2>
Since this is not mentioned in the limitations of Basic AGs, I consider this as supported. In my test environment, I’m using the new test database <a target="_blank" href="https://github.com/Microsoft/sql-server-samples/tree/master/samples/databases/wide-world-importers" rel="noopener">WideWorldImporters</a> which is actually using FILESTREAM because it’s using In-Memory OLTP tables. More information on FILESTREAM and FileTable with AlwaysOn Availability Groups can be found <a target="_blank" href="https://msdn.microsoft.com/en-us/library/hh510261.aspx" rel="noopener">here</a>.

&nbsp;

<a href="https://msdnshared.blob.core.windows.net/media/2017/03/image345.png"><img width="1104" height="430" title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/03/image_thumb337.png" border="0" /></a>

&nbsp;
<h2>5. Can I have SQL FCI as a replica?</h2>
<span style="font-size: small">Basic Availability Groups are limited to 2 replicas, 1 primary and 1 secondary. A replica is an <u>instance</u> of SQL Server. So, it doesn’t matter if your instance is clustered. This means that 1 or both of the replicas can be a failover cluster instance in a Basic Availability Group. The only thing that you have to be aware of is that Automatic Failover will not work in this case as this is handled by the FCI. But that’s the same behavior as in Enterprise Edition. In my example, I’ve created 1 FCI SQL\INST which is currently my primary and 1 stand-alone secondary. And as you can see, it works like a charm.</span>

&nbsp;

<span style="font-size: small"></span>

<a href="https://msdnshared.blob.core.windows.net/media/2017/03/image346.png"><img width="638" height="266" title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/03/image_thumb338.png" border="0" /></a>

<a href="https://msdnshared.blob.core.windows.net/media/2017/03/image347.png"><img width="636" height="372" title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/03/image_thumb339.png" border="0" /></a>
<h2>6. Do I need a listener for each group?</h2>
<span>If you have multiple databases on you instance and each database is part of 1 single group, do you need to create a group listener for each group.
The short answer is "you don't". If you create a single listener on 1 group, you can use it for other database that are part of another group.
In the example below, you can see I have only 1 listener but 3 groups. The salesdb is not part of the group where the listener is configure but I can still access the database.
</span>

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/Listener.jpg"><img width="413" height="601" class="alignnone wp-image-875" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/12/Listener-206x300.jpg" /></a>

Of course, there is a drawback on this. As soon as the group BASIC_AG1 does a failover, the salesdb will not be accessible anymore because the listener is now pointing to another replica. To avoid this "split" situation you can manually failover the other groups to the other replica as well or you should create a group listener on each group.
<h2>7. Can I take a snapshot of the database that is running on the secondary replica?</h2>
Yes, the snapshot works on the secondary replica. This behavior is the same when you should have used database mirroring in the past. You could also take a snapshot of the mirrored database.

<span style="font-size: small">If you should have any other questions about Basic Availability Groups, please let me know. I’m happy to test it and figure it out.</span>

<span style="font-size: small"></span>

<span style="font-size: small">Pieter</span>]]></content:encoded>
    </item>
    <item>
      <title>How to Set Up Basic Availability Groups in SQL Server 2016</title>
      <link>https://docs.microsoft.com/archive/blogs/msftpietervanhove/how-to-set-up-basic-availability-groups-in-sql-server-2016</link>
      <pubDate>Tue, 10 May 2016 21:31:26 GMT</pubDate>
      <dc:creator><![CDATA[Pieter Vanhove]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/msftpietervanhove/?p=757</guid>
      <description><![CDATA[AlwaysOn Basic Availability Groups provide a high availability solution for SQL Server 2016 Standard...]]></description>
      <content:encoded><![CDATA[<p><a href="https://msdn.microsoft.com/en-us/library/mt614935.aspx" target="_blank">AlwaysOn Basic Availability Groups</a> provide a high availability solution for SQL Server 2016 Standard Edition. This new functionality will replace database mirroring, which is a deprecated feature. Basic Availability Groups are managed and created in the same way like the traditional Enterprise AlwaysOn Availability Group, but there are more limitations which are almost equally when you should run Database Mirroring on a Standard Edition. With this blog post I want to show how easy it is to create a Basic Availability Group and what limitations you can expect.</p> <h2>Prerequisites</h2> <p>The prerequisites are the same as for a traditional Enterprise AlwaysOn Availability Group. You still need to Create a Windows Failover Cluster and Enable AlwaysOn Availability Groups on each instance. More information can be found on <a href="https://msdn.microsoft.com/en-us/library/ff878487.aspx" target="_blank">Prerequisites, Restrictions, and Recommendations for AlwaysOn Availability Groups</a></p> <h2>Setup a New Basic Availability Group</h2> <p>You can still use the “New Availability Group Wizard” in the management studio to create your basic Availability Group. Of course, T-SQL and PowerShell can also be used.</p> <p>Specify the name of the Availability that you want to create.</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/05/image418.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/05/image_thumb362.png" width="244" height="116"></a></p> <p>Please also note the new option “Database level Health Detection”. You can now configure AlwaysOn Availability Groups to failover when a database goes offline. This was not possible in previous editions of SQL Server.</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/05/image419.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/2016/05/image_thumb363.png" width="647" height="360"></a></p> <p>Select the database that you want to add to the Availability Group. One of the limitations of Basic HA is that you’re only allowed to add 1 database per group. The wizard will return an error when you try to add more than 1 database into the group.</p> <p>When you specify the replicas for your Availability Group, you will notice 2 other limitations:</p> <ul> <li>Limit of two replicas (primary and secondary). After you’ve added the secondary replica, the “Add Replica” button will automatically be disabled. <li>No read access on secondary replica. The wizard only has the “No” option, so you can’t configure a readable secondary.</li></ul> <p>&nbsp;</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/05/image420.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/2016/05/image_thumb364.png" width="589" height="263"></a></p> <p>Please note that you can configure Synchronous or Asynchronous commit mode. This is a difference compared to database mirroring where you could only use synchronous commit mode in SQL Server Standard Edition. With Basic HA, we allow asynchronous commit mode, to be able to create your secondary replica in Azure. This allows you to create even a basic disaster recovery solution with SQL Server Standard Edition!</p> <p>The endpoint configuration is still needed and there is no difference compared to the traditional Enterprise Availability Groups</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/05/image421.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/2016/05/image_thumb365.png" width="574" height="170"></a></p> <p>Basic HA doesn’t allow you to use a readable secondary, which means that there are no backups possible on the secondary replica. You will notice that the Backup Preferences are completely disabled</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/05/image422.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/2016/05/image_thumb366.png" width="572" height="388"></a></p> <p>Basic HA also supports the usage of an Availability Group Listener. Creating the listener is the same procedure as the traditional Enterprise listener. The Basic HA group is limited to 1 listener.</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/05/image423.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/2016/05/image_thumb367.png" width="570" height="376"></a></p> <p>&nbsp;</p> <p>The next step is setting up the data synchronization between the 2 replicas. Again, there is no difference here between Standard and Enterprise Edition</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/05/image424.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/2016/05/image_thumb368.png" width="561" height="301"></a></p> <p>With SQL Sever 2016, you could also use the new option Direct Seeding. This method will seed the secondary replica over the network. It does not require you to backup and restore a copy of the primary database on the replica. However, this is currently not available in the wizard but only with T-SQL.</p> <p>After you finish the wizard, you have setup your first Basic HA Availability Group.</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/05/image425.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/2016/05/image_thumb369.png" width="291" height="191"></a></p>]]></content:encoded>
    </item>
    <item>
      <title>-m Startup Parameter issues</title>
      <link>https://docs.microsoft.com/archive/blogs/msftpietervanhove/m-startup-parameter-issues</link>
      <pubDate>Thu, 03 Mar 2016 16:51:20 GMT</pubDate>
      <dc:creator><![CDATA[Pieter Vanhove]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/msftpietervanhove/?p=661</guid>
      <description><![CDATA[This week I delivered a disaster recovery workshop at one of clients. One of the tasks is to startup...]]></description>
      <content:encoded><![CDATA[This week I delivered a disaster recovery workshop at one of clients. One of the tasks is to startup the SQL Server in a single user mode to restore the master database for example. I ran into a weird situation that I would like to share.

When you startup SQL Server in single user mode, by using the –m startup parameter, you get 1 single connection to the instance. In some circumstances there might be applications that are faster than you and will take that single connection… Result… you’re not able to connect anymore… and you will get this error.

<a href="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image0021.jpg"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="clip_image002" src="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image002_thumb1.jpg" alt="clip_image002" width="607" height="168" border="0" /></a>

To avoid this issue, you can limit the connections to a specified client application, for example SQL Server Management Studio or sqlcmd.
When you check the <a href="https://msdn.microsoft.com/en-us/library/ms188236.aspx" target="_blank">documentation</a>, you need to add the name of the application just after the –m. Great, I only want to allow connections from the SQL Server Management Studio.
To connect through the Query Editor in the SQL Server Management Studio I have to use <strong>-m"Microsoft SQL Server Management Studio - Query"</strong>.

When I add the startup parameter in the SQL Server Configuration Manager, I get the following error:

<a href="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image0026.jpg"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="clip_image002[6]" src="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image0026_thumb.jpg" alt="clip_image002[6]" width="461" height="300" border="0" /></a>

I removed the – Query and it worked. After investigating the code in SqlManager.dll, together with my colleague PFE Nacho (<a href="https://blogs.msdn.com/b/ialonso/" target="_blank">blog</a>), we figured out that a dash (-) or a forward slash (/), other than the one at the first position, is considered as an invalid value. A possible workaround for this is adding the value directly in to the registry of the server.

Open regedit and go to HKEY_LOCAL_MACHINE – Software – Microsoft – Microsoft SQL Server – (name of your instance) MSSQL12.MSSQLSERVER – MSSQLServer – Parameters and add the –m startup parameter here

<a href="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image0028.jpg"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="clip_image002[8]" src="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image0028_thumb.jpg" alt="clip_image002[8]" width="493" height="206" border="0" /></a>

I managed now to get the startup parameter in place, restarted the service so that my instance is started in single user mode and it will only allow connection from the Query Editor of the SQL Server Management Studio. Make sure when you open the SQL Server Management Studio that you don’t open the object explorer.  It might fail because it requires more than one connection for some operations. When I tried to connect to my instance, I got the same “Login Failed” error again. According to the documentation I did everything correct… After investigating the SQL code again, we have found that actually what is passed as the input string, is everything you put after the –m, <span style="text-decoration: underline">including leading/trailing spaces, quotes, double quotes, brackets, etc</span>. If that doesn’t match exactly (binary comparison) with what you pass in your login packet as the application name, then you get that Login Failed error.

Notice that if you set your startup parameter like any of these cases, they will never match to what you can pass over the connection string attribute, and you will get the error I was observing.

1. Prefixing and suffixing quotes which you cannot get as part of the application name provided by the client

-m”Microsoft SQL Server Management Studio - Query”

2. Leading and trailing blanks (spaces) which you would only get as part of the application name provided by the client if it was enclosed in quotes so that the spaces didn’t get trimmed out

-m     Microsoft SQL Server Management Studio - Query

Other reasons why you would get that logon error are because:
<ol>
	<li>The login is not a member of sysadmin fixed server role,</li>
	<li>The server is in running upgrade scripts mode and you’re not connecting over DAC,</li>
	<li>The ID of the session (SPID) you already used once to connect through this mechanism is different than that of the session ID you’re trying to use right now (i.e. attempting to connect over more than one session)</li>
</ol>
Now that this is sorted out, let’s change the startup parameter into Microsoft SQL Server Management Studio – Query, without the double quotes.

<a href="https://msdnshared.blob.core.windows.net/media/2016/03/image35.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/03/image_thumb25.png" alt="image" width="395" height="179" border="0" /></a>

After I restarted the service and tried to connect again with the Query Editor I still got the some Login Failed error… Now, I was pretty sure that my startup parameter was correct. But what about my application name in my connection?

It seems when you open a Query Editor window without connecting to the instance with the Object Explorer, the application name is change to Microsoft SQL Server Management Studio!

<a href="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image001.jpg"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="clip_image001" src="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image001_thumb.jpg" alt="clip_image001" width="529" height="35" border="0" /></a>

However, when you open the SQL Server Management Studio when the instance is not in single user mode, you connect to the instance with the Object Explorer and you open a new query window, the application name of that session is Microsoft SQL Server Management Studio – Query

<a href="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image00210.jpg"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="clip_image002[10]" src="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image00210_thumb.jpg" alt="clip_image002[10]" width="529" height="41" border="0" /></a>

To conclude, the correct startup parameter should be Microsoft SQL Server Management Studio, and not –m”Microsoft SQL Server Management Studio – Query” as mentioned in the documentation.

<a href="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image0016.jpg"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="clip_image001[6]" src="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image0016_thumb.jpg" alt="clip_image001[6]" width="341" height="161" border="0" /></a>

After the restart of my instance, I was finally able to connect with the Query Editor to my instance that was in single user mode.

We have already filed 2 defects internally to get those issues fixed and the documentation will be changed.

Pieter]]></content:encoded>
    </item>
    <item>
      <title>The order of automatic failover</title>
      <link>https://docs.microsoft.com/archive/blogs/msftpietervanhove/the-order-of-automatic-failover</link>
      <pubDate>Sun, 14 Feb 2016 12:27:47 GMT</pubDate>
      <dc:creator><![CDATA[Pieter Vanhove]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/msftpietervanhove/?p=541</guid>
      <description><![CDATA[One of the new features that has been added in SQL Server 2016 for High Availability is the...]]></description>
      <content:encoded><![CDATA[One of the new features that has been added in <a href="https://msdn.microsoft.com/en-us/library/bb510411.aspx#HighAvailability" target="_blank">SQL Server 2016 for High Availability</a> is the possibility to configure 3 replicas for automatic failover. In SQL Server 2014, it was only possible to configure 2 automatic failover replicas. But how is SQL Server going to decide to which replica it will failover first? Imagine that you have an AlwaysOn Availability Group configuration with 3 nodes. Node 1 is primary, Node 2 and 3 are secondaries. All three replicas are configured for automatic failover. Will it failover first to Node 2 and then Node 3, or the other way around? Well, let’s figure out how it works!

First of all, I’ve added Node 2 and 3 to my availability group as secondary replicas.

<a href="https://msdnshared.blob.core.windows.net/media/2016/02/image96.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/02/image_thumb86.png" alt="image" width="594" height="147" border="0" /></a>

&nbsp;

If you verify the Preferred Owners of your Availability Group Role in the Failover Cluster Manager, you will notice that the order will be the same as you have added the replicas to the availability group. This means if Node1 becomes unavailable, Node 2 should become the new primary.

<a href="https://msdnshared.blob.core.windows.net/media/2016/02/image97.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/02/image_thumb87.png" alt="image" width="402" height="239" border="0" /></a>

&nbsp;

During my tests, I’ve stopped the SQL Server Service to verify the automatic failover. And as expected, Node 2 became my new primary replica.

<a href="https://msdnshared.blob.core.windows.net/media/2016/02/image98.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/02/image_thumb88.png" alt="image" width="341" height="189" border="0" /></a>

If we look back at the preferred owners in the Failover Cluster Manager, you will notice that the order of the Preferred Owners has changed.

<a href="https://msdnshared.blob.core.windows.net/media/2016/02/image99.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/02/image_thumb89.png" alt="image" width="337" height="220" border="0" /></a>

&nbsp;

Secondly I make Node 2 also unavailable. I expect that Node 3 will become my new primary as Node 1 is still down.

<a href="https://msdnshared.blob.core.windows.net/media/2016/02/image100.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/02/image_thumb90.png" alt="image" width="336" height="196" border="0" /></a>

And again, the order of the Preferred Owners has changed.

<a href="https://msdnshared.blob.core.windows.net/media/2016/02/image101.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/02/image_thumb92.png" alt="image" width="349" height="169" border="0" /></a>

&nbsp;

For my second test, I added the secondary replicas in a different order, first Node 3 and secondly Node 2.

<a href="https://msdnshared.blob.core.windows.net/media/2016/02/image102.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/02/image_thumb93.png" alt="image" width="393" height="147" border="0" /></a>

In the Object Explorer, you will see that the replicas are added again in alphabetical order.

<a href="https://msdnshared.blob.core.windows.net/media/2016/02/image103.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/02/image_thumb94.png" alt="image" width="305" height="175" border="0" /></a>

However, if you check again the Preferred Owners of the Availability Group Cluster role, you will see that now the order of the replicas is the same like I’ve added them to the availability group.

<a href="https://msdnshared.blob.core.windows.net/media/2016/02/image104.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/02/image_thumb95.png" alt="image" width="368" height="186" border="0" /></a>

&nbsp;

I disabled the SQL Server service on Node 1 again and as expected Node 3 became my new primary replica.

To conclude, the nodes are given to the cluster in the order that they were added to the AlwaysOn Availability Group.  SQL Server iterates the replica list in the availability group and does not reorder. Microsoft does not support manual updates to the cluster config for the availability group.  There have been problems with users getting into the config and breaking failover or disabling the full availability group.  We readjust preferred owners to what we think it should be every time something changes so even if the user changed the order we might reset it back to what we think it should be.

To change the failover order you will have to drop the replica and then add it back in, so it is after the other replica.]]></content:encoded>
    </item>
    <item>
      <title>Backup to Azure WITH CREDENTIAL (deprecated) or SAS Token</title>
      <link>https://docs.microsoft.com/archive/blogs/msftpietervanhove/backup-to-azure-with-credential-deprecated-or-sas-token</link>
      <pubDate>Fri, 05 Feb 2016 10:20:44 GMT</pubDate>
      <dc:creator><![CDATA[Pieter Vanhove]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/msftpietervanhove/?p=381</guid>
      <description><![CDATA[Since SQL Server 2012 SP1 CU2 or later and SQL Server 2014 it is possible to use the Microsoft Azure...]]></description>
      <content:encoded><![CDATA[Since SQL Server 2012 SP1 CU2 or later and SQL Server 2014 it is possible to use the Microsoft Azure Blob storage service as a backup destination. One of the key compentents in SQL Server that you need is a credential. SQL Server backup and restore processes use this credential to authenticate to the Windows Azure Blob storage service.

For general information about credentials, see <a href="https://msdn.microsoft.com/en-us/library/ms161950.aspx" target="_blank">Credentials</a>.

Once the credential is created, it must be specified in the WITH clause when issuing the BACKUP/RESTORE statements.
<pre style="overflow: visible;;background: white;;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;line-height: normal;padding-right: 0px;border-style: none"><span style="color: #0000ff">BACKUP</span><span style="color: #000000"> </span><span style="color: #0000ff">DATABASE</span><span style="color: #000000"> AdventureWorks2014  
</span><span style="color: #0000ff">TO</span><span style="color: #000000"> URL </span><span style="color: #808080">=</span><span style="color: #000000"> </span><span style="color: #ff0000">'https://mystorageaccount.blob.core.windows.net/mycontainer/AdventureWorks2014.bak' 
</span><span style="color: #0000ff">WITH</span><span style="color: #000000"> </span><span style="color: #0000ff">CREDENTIAL</span><span style="color: #000000"> </span><span style="color: #808080">=</span><span style="color: #000000"> </span><span style="color: #ff0000">'mycredential'</span><span style="color: #808080">,</span><span style="color: #0000ff">COMPRESSION</span><span style="color: #808080">, </span><span style="color: #008000">STATS</span><span style="color: #000000"> </span><span style="color: #808080">=</span><span style="color: #000000"> 5</span><span style="color: #808080">;</span>
<span style="color: #0000ff">GO</span><span style="color: #000000"> </span></pre>
In SQL Server 2016, you still have to use a credential, however, the credential can either store the name of the storage account and the storage account access key values <strong><span style="font-size: large">or</span></strong> container URL and its <a href="https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-shared-access-signature-part-1/" target="_blank">Shared Access Signature</a> token. To create a SAS key, you can use the script that you can find on <a href="https://msdn.microsoft.com/en-us/library/dn435916(v=sql.130).aspx#SAS" target="_blank">https://msdn.microsoft.com/en-us/library/dn435916(v=sql.130).aspx#SAS</a> or use the <a href="https://azurestorageexplorer.codeplex.com/" target="_blank">Azure Storage Explorer</a> if you prefer a GUI. Make sure you download version 5 because I’ve noticed that the SAS key generation in version 6 is not working correctly. In <a href="https://www.mssqlgirl.com/sql-server-2014-in-a-jiffy-credential-for-windows-azure-storage.html" target="_blank">this blog post</a> of Julie Koesmarno (<a href="https://twitter.com/mssqlgirl" target="_blank">t</a> | <a href="https://www.mssqlgirl.com/" target="_blank">b</a>) you get a good explanation how to do this. When creating the credential, make sure you consider the following:
<ul>
	<li>The name of the credential must match the container path</li>
	<li>IDENTITY='SHARED ACCESS SIGNATURE' , this is a mandatory string and cannot be changed</li>
	<li>use the SAS key in the secret clause</li>
</ul>
There are several methods to create the credential. You could use the following T-SQL example
<pre style="overflow: visible;;background: white;;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;line-height: normal;padding-right: 0px;border-style: none"><span style="color: #0000ff">USE</span><span style="color: #000000"> </span><span style="color: #0000ff">master</span>
<span style="color: #0000ff">GO</span>
<span style="color: #0000ff">CREATE</span><span style="color: #000000"> </span><span style="color: #0000ff">CREDENTIAL</span><span style="color: #000000"> </span><span style="color: #ff0000">'https://&lt;mystorageaccountname&gt;.blob.core.windows.net/&lt;mystorageaccountcontainername&gt;'</span><span style="color: #000000"> </span><span style="color: #008000">-- this name must match the container path, start with https and must not contain a forward slash.</span>
<span style="color: #000000">   </span><span style="color: #0000ff">WITH</span><span style="color: #000000"> </span><span style="color: #0000ff">IDENTITY</span><span style="color: #808080">=</span><span style="color: #ff0000">'SHARED ACCESS SIGNATURE'</span><span style="color: #000000"> </span><span style="color: #008000">-- this is a mandatory string and do not change it. </span>
<span style="color: #000000">   </span><span style="color: #808080">,</span><span style="color: #000000"> </span><span style="color: #0000ff">SECRET</span><span style="color: #000000"> </span><span style="color: #808080">=</span><span style="color: #000000"> </span><span style="color: #ff0000">'&lt;SAS Token&gt;'</span><span style="color: #000000"> </span><span style="color: #008000">-- this is the shared access signature key that you obtained in Lesson 1. </span>
<span style="color: #0000ff">GO</span></pre>
or you can use the GUI in the SQL Server Management Studio. Connect to your instance with the Object Explorer, select Security, right click on Credentials and select New Credential.

<a href="https://msdnshared.blob.core.windows.net/media/2016/02/image13.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="image" src="https://msdnshared.blob.core.windows.net/media/2016/02/image_thumb7.png" alt="image" width="749" height="231" border="0" /></a>

&nbsp;

Once the credential is created, you can issue your BACKUP/RESTORE commands. Please note that the WITH CREDENTIAL clause is not necessary anymore.
<pre style="overflow: visible;;background: white;;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;line-height: normal;padding-right: 0px;border-style: none"><span style="color: #0000ff">BACKUP</span><span style="color: #000000"> </span><span style="color: #0000ff">DATABASE</span><span style="color: #000000"> AdventureWorks2016  
</span><span style="color: #0000ff">TO</span><span style="color: #000000"> URL </span><span style="color: #808080">=</span><span style="color: #000000"> </span><span style="color: #ff0000">'https://&lt;mystorageaccountname&gt;.blob.core.windows.net/&lt;mycontainername&gt;/AdventureWorks2016.bak'</span><span style="color: #808080">;</span>
<span style="color: #0000ff">GO</span></pre>
<span style="color: #000000">Although both WITH CREDENTIAL and SAS key are possible in SQL Server 2016, we recommend to use the SAS token when performing backups to Microsoft Azure Blob storage service. In fact, the WITH CREDENTIAL is <a href="https://msdn.microsoft.com/en-us/library/dn466436.aspx" target="_blank">deprecated</a>. Currently the documentation is not updated yet, but this will be done quite soon. More information on SQL Server Backup to URL in SQL Server 2016 can be found on <a href="https://msdn.microsoft.com/en-us/library/dn435916(v=sql.130).aspx" target="_blank">https://msdn.microsoft.com/en-us/library/dn435916(v=sql.130).aspx</a>.</span>

<span style="color: #000000">Pieter</span>]]></content:encoded>
    </item>
    <item>
      <title>Generate workload on your Azure SQL Database</title>
      <link>https://docs.microsoft.com/archive/blogs/msftpietervanhove/generate-workload-on-your-azure-sql-database</link>
      <pubDate>Fri, 08 Jan 2016 16:56:05 GMT</pubDate>
      <dc:creator><![CDATA[Pieter Vanhove]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/msftpietervanhove/?p=191</guid>
      <description><![CDATA[At the end of last year, we have announced the Azure SQL Database Index Advisor which recommends new...]]></description>
      <content:encoded><![CDATA[At the end of last year, we have announced the <a target="_blank" href="https://azure.microsoft.com/en-us/documentation/articles/sql-database-index-advisor/">Azure SQL Database Index Advisor</a> which recommends new indexes for your existing SQL Databases that can improve your query performance. One of the prerequisites to get index recommendations is to have database usage of course. This blog post will explain how you can generate SQL load on your Azure SQL Database. I’m going to use the AdventureWorks database as an example.
<h3>Create your Azure SQL Sample Database</h3>
There are several possibilities to create a sample database. You can migrate your on-premise database to an Azure Database. There are various approaches to migrate your database. Checkout  our <a target="_blank" href="https://azure.microsoft.com/en-us/blog/migration-cookbook-now-available-for-the-latest-azure-sql-database-update-v12/">Migration cookbook</a>. Another possibility is using a light version of the AdventureWorks database. Microsoft currently provides this database as a sample database in the Azure Portal.

<a href="https://msdnshared.blob.core.windows.net/media/2016/01/AdventureWorks-Sample-Database1.jpg"><img width="253" height="408" title="AdventureWorks Sample Database" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="AdventureWorks Sample Database" src="https://msdnshared.blob.core.windows.net/media/2016/01/AdventureWorks-Sample-Database_thumb1.jpg" border="0" /></a>

I’ve used the <a target="_blank" href="https://msftdbprodsamples.codeplex.com/releases/view/125550">AdventureWorks2014</a> database for my tests.
<h4></h4>
<h3>Generate SQL Workload Script</h3>
Next to the database you need to have sample queries that you can execute against the database. You can find a lot of <a target="_blank" href="https://msdn.microsoft.com/en-us/library/ms187731(v=sql.110).aspx">sample queries</a> on Books Online. The idea is to randomly execute the queries against the database. Jonathan Kehayias (<a target="_blank" href="https://www.sqlskills.com/blogs/jonathan/">blog</a> | <a target="_blank" href="https://twitter.com/SQLPoolBoy">twitter</a>) created a <a target="_blank" href="https://www.sqlskills.com/blogs/jonathan/the-adventureworks2008r2-books-online-random-workload-generator/">very nice solution</a> a few years ago to generate random workload. He created a large T-SQL script file with all the sample queries in it. A PowerShell script selects randomly one of the queries and executes it against the database. I really liked the idea and tried to run Jonathan’s solution against my Azure SQL Database. I just had to modify a few of the T-SQL statements because some of the syntax is not supported on Azure DB, like USE and GO. I also modified the PowerShell script a bit so that I was able to connect to my Azure database.

You can download the modified PowerShell and the large T-SQL file <a target="_blank" href="https://1drv.ms/f/s!Aqp_NUQYhSLGjsxTFSE0PGfXJKOVfg">here</a>.
<h4></h4>
<h4></h4>
<h3>Generating the workload</h3>
One of the possibilities is running the above mentioned scripts locally. However, before you can get index recommendations on your Azure DB, the load has to be running at least for a few days. In my situation, I couln’t leave my laptop open for 24/7. I decided to spin up an Azure VM and run the scripts from that virtual machine. That solution worked perfectly but I had use a VM which will give an additional cost. So, I have worked out another way to schedule the SQL workload, without the Azure VM. And when you say *schedule*, you think immediatly about Azure Automation, right? I’ve created a solution that is based on an Azure Runbook and Azure Table. The Runbook is going to replace the PowerShell script and the Azure Table will contain the sample queries of the large T-SQL script.
<h4></h4>
<h4></h4>
<h4>Create the Azure Table</h4>
The first step is creating the Azure Table, which has to be done with another PowerShell script. In the Azure documentation you can find some very usefull examples <a target="_blank" href="https://azure.microsoft.com/en-us/documentation/articles/storage-powershell-guide-full/#how-to-manage-azure-tables-and-table-entities">how to manage Azure tables and table entities</a>. The Azure Table will contain all the AdventureWorks sample queries and exists out of 2 columns which is an ID and the query to execute. You can download the scripts to create and to load the Azure table <a target="_blank" href="https://1drv.ms/f/s!Aqp_NUQYhSLGjsxTFSE0PGfXJKOVfg">here</a>.

To verify the content of your Azure Table, you have to use the  <a href="https://msdn.microsoft.com/library/azure/microsoft.windowsazure.storage.table.tablequery.aspx">Microsoft.WindowsAzure.Storage.Table.TableQuery</a> class or use the <a target="_blank" href="https://azurestorageexplorer.codeplex.com/">Azure Storage Explorer</a> if you prefer a GUI.
<h4>Create the Runbook</h4>
By creating a Runbook, you can radomly select one of the queries that are stored in the Azure Table and execute it against your Azure SQL Database.
Before you can create the Runbook, you first have to create an new Azure Automation Account. Go to the Azure Portal, select Automation Accounts and click the Add button. Specify the Name, Resource Group, Subscription and the Region.

<a href="https://msdnshared.blob.core.windows.net/media/2016/01/image59.png"><img width="271" height="400" title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/01/image_thumb57.png" border="0" /></a>

Once your Automation Account is created, you have to create a credential Asset. It contains the username and password for the target Azure SQL Database logical server.
Go to the Automation Account you’ve just created and select Assets – Credentials

<a href="https://msdnshared.blob.core.windows.net/media/2016/01/image30.png"><img width="178" height="88" title="image" style="padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px;border-width: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/01/image_thumb30.png" border="0" /></a> <a href="https://msdnshared.blob.core.windows.net/media/2016/01/image31.png"><img width="177" height="177" title="image" style="padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px;border-width: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/01/image_thumb31.png" border="0" /></a>

Click on the button Add a Credential and specify the Credential Name, User name and password.

<a href="https://msdnshared.blob.core.windows.net/media/2016/01/image91.png"><img width="267" height="434" title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/01/image9_thumb.png" border="0" /></a>

We have now setup all the prerequisites so we can start with creating a runbook in our Azure Automation account. A runbook is a PowerShell Workflow that needs to be created or imported. The runbook contains the script to randomly get a query from the Azure Table and execute it against the Azure Database. Select your Automation Account and click on Runbook.

<a href="https://msdnshared.blob.core.windows.net/media/2016/01/image33.png"><img width="179" height="90" title="image" style="padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px;border-width: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/01/image_thumb33.png" border="0" /></a>

Click on the button Add a runbook. Below you can find the runbook that I’ve created. You can either copy/paste it into a new runbook or save it locally and then import it.
<pre style="overflow: visible;;background: white;;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;line-height: normal;padding-right: 0px;border-style: none"><span style="color: #006400">&lt;#
.SYNOPSIS  Generate SQL Workload on AdventureWorks   .DESCRIPTION  Generate SQL Workload on AdventureWorks    .EXAMPLE  SQLWorkload    .NOTES  AUTHOR: Pieter Vanhove  LAST EDIT: December 31, 2015  #&gt;</span>
<span style="color: #000000">  </span><span style="color: #00008b">workflow</span><span style="color: #000000"> </span><span style="color: #8a2be2">SQLWorkload</span>
<span style="color: #000000">{  </span><span style="color: #00008b">param</span>
<span style="color: #000000"> (  </span><span style="color: #006400"># Fully-qualified name of the Azure DB server </span>
<span style="color: #000000"> </span><span style="color: #a9a9a9">[</span><span style="color: #00bfff">parameter</span><span style="color: #000000">(Mandatory</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$true</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span><span style="color: #000000">   </span><span style="color: #a9a9a9">[</span><span style="color: #008080">string</span><span style="color: #a9a9a9">]</span><span style="color: #000000"> </span><span style="color: #ff4500">$SqlServerName</span><span style="color: #a9a9a9">,</span>
<span style="color: #000000">   </span><span style="color: #006400"># Fully-qualified name of the Azure DB server </span>
<span style="color: #000000"> </span><span style="color: #a9a9a9">[</span><span style="color: #00bfff">parameter</span><span style="color: #000000">(Mandatory</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$true</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span><span style="color: #000000">   </span><span style="color: #a9a9a9">[</span><span style="color: #008080">string</span><span style="color: #a9a9a9">]</span><span style="color: #000000"> </span><span style="color: #ff4500">$SqlDatabaseName</span><span style="color: #a9a9a9">,</span>
<span style="color: #000000">   </span><span style="color: #006400"># Credentials for $SqlServerName stored as an Azure Automation credential asset</span>
<span style="color: #000000"> </span><span style="color: #006400"># When using in the Azure Automation UI, please enter the name of the credential asset for the "Credential" parameter</span>
<span style="color: #000000"> </span><span style="color: #a9a9a9">[</span><span style="color: #00bfff">parameter</span><span style="color: #000000">(Mandatory</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$true</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span><span style="color: #000000">   </span><span style="color: #a9a9a9">[</span><span style="color: #008080">PSCredential</span><span style="color: #a9a9a9">]</span><span style="color: #000000"> </span><span style="color: #ff4500">$Credential</span><span style="color: #a9a9a9">,</span>
<span style="color: #000000">   </span><span style="color: #006400"># The storage account where the Azure Table is stored</span>
<span style="color: #000000"> </span><span style="color: #a9a9a9">[</span><span style="color: #00bfff">parameter</span><span style="color: #000000">(Mandatory</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$true</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span><span style="color: #000000">   </span><span style="color: #a9a9a9">[</span><span style="color: #008080">string</span><span style="color: #a9a9a9">]</span><span style="color: #000000"> </span><span style="color: #ff4500">$StorageAccount</span><span style="color: #a9a9a9">,</span>
<span style="color: #000000">   </span><span style="color: #006400"># Define the Storage Account Key</span>
<span style="color: #000000"> </span><span style="color: #a9a9a9">[</span><span style="color: #00bfff">parameter</span><span style="color: #000000">(Mandatory</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$true</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span><span style="color: #000000">   </span><span style="color: #a9a9a9">[</span><span style="color: #008080">string</span><span style="color: #a9a9a9">]</span><span style="color: #000000"> </span><span style="color: #ff4500">$StorageKey</span>
<span style="color: #000000">    )     </span><span style="color: #0000ff">inlinescript</span><span style="color: #000000">{     </span><span style="color: #006400"># Setup credentials and parameters </span>
<span style="color: #000000"> </span><span style="color: #ff4500">$ServerName</span><span style="color: #000000"> </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #ff4500">$Using:SqlServerName</span>
<span style="color: #000000"> </span><span style="color: #ff4500">$DatabaseName</span><span style="color: #000000"> </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #ff4500">$Using:SqlDatabaseName</span>
<span style="color: #000000"> </span><span style="color: #ff4500">$UserId</span><span style="color: #000000"> </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #ff4500">$Using:Credential</span><span style="color: #a9a9a9">.</span><span style="color: #000000">UserName  </span><span style="color: #ff4500">$Password</span><span style="color: #000000"> </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> (</span><span style="color: #ff4500">$Using:Credential</span><span style="color: #000000">)</span><span style="color: #a9a9a9">.</span><span style="color: #000000">GetNetworkCredential()</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Password  </span><span style="color: #ff4500">$StorageAccountName</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$Using:StorageAccount</span>
<span style="color: #000000"> </span><span style="color: #ff4500">$StorageAccountKey</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$Using:StorageKey</span>
<span style="color: #000000">   </span><span style="color: #006400"># Create connection for the database</span>
<span style="color: #000000"> </span><span style="color: #ff4500">$DatabaseConnection</span><span style="color: #000000"> </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #0000ff">New-Object</span><span style="color: #000000"> </span><span style="color: #8a2be2">System.Data.SqlClient.SqlConnection</span>
<span style="color: #000000"> </span><span style="color: #ff4500">$DatabaseCommand</span><span style="color: #000000"> </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #0000ff">New-Object</span><span style="color: #000000"> </span><span style="color: #8a2be2">System.Data.SqlClient.SqlCommand</span>
<span style="color: #000000">   </span><span style="color: #006400">#Create Azure Storage Context </span>
<span style="color: #000000"> </span><span style="color: #ff4500">$Ctx</span><span style="color: #000000"> </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #0000ff">New-AzureStorageContext</span><span style="color: #000000"> </span><span style="color: #ff4500">$StorageAccountName</span><span style="color: #000000"> </span><span style="color: #000080">-StorageAccountKey</span><span style="color: #000000"> </span><span style="color: #ff4500">$StorageAccountKey</span>
<span style="color: #000000"> </span><span style="color: #ff4500">$TableName</span><span style="color: #000000"> </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #8b0000">"SQLWorkload"</span>
<span style="color: #000000">   </span><span style="color: #006400">#Get a reference to a table.</span>
<span style="color: #000000"> </span><span style="color: #ff4500">$table</span><span style="color: #000000"> </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #0000ff">Get-AzureStorageTable</span><span style="color: #000000"> </span><span style="color: #000080">–Name</span><span style="color: #000000"> </span><span style="color: #ff4500">$TableName</span><span style="color: #000000"> </span><span style="color: #000080">-Context</span><span style="color: #000000"> </span><span style="color: #ff4500">$Ctx</span>
<span style="color: #000000">   </span><span style="color: #006400">#Create a table query.</span>
<span style="color: #000000"> </span><span style="color: #ff4500">$TableQuery</span><span style="color: #000000"> </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #0000ff">New-Object</span><span style="color: #000000"> </span><span style="color: #8a2be2">Microsoft.WindowsAzure.Storage.Table.TableQuery</span>
<span style="color: #000000">  </span><span style="color: #006400">#Define columns to select.</span>
<span style="color: #000000"> </span><span style="color: #ff4500">$list</span><span style="color: #000000"> </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #0000ff">New-Object</span><span style="color: #000000"> </span><span style="color: #8a2be2">System.Collections.Generic.List[string]</span>
<span style="color: #000000"> </span><span style="color: #ff4500">$list</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Add(</span><span style="color: #8b0000">"Query"</span><span style="color: #000000">)
 
 
</span><span style="color: #00008b">WHILE</span><span style="color: #000000">(</span><span style="color: #800080">1</span><span style="color: #000000"> </span><span style="color: #a9a9a9">-eq</span><span style="color: #000000"> </span><span style="color: #800080">1</span><span style="color: #000000">)   {      </span><span style="color: #006400"># Pick a Random Query from the input object </span>
<span style="color: #000000">    </span><span style="color: #ff4500">$ID</span><span style="color: #000000"> </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #0000ff">Get-Random</span><span style="color: #000000"> </span><span style="color: #000080">-Minimum</span><span style="color: #000000"> </span><span style="color: #800080">1</span><span style="color: #000000"> </span><span style="color: #000080">-Maximum</span><span style="color: #000000"> </span><span style="color: #800080">38</span><span style="color: #000000">;     </span><span style="color: #0000ff">Write-Output</span><span style="color: #000000"> </span><span style="color: #ff4500">$ID</span>
<span style="color: #000000">    </span><span style="color: #006400">#Set query details.</span>
<span style="color: #000000">    </span><span style="color: #ff4500">$TableQuery</span><span style="color: #a9a9a9">.</span><span style="color: #000000">FilterString </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #8b0000">"ID eq </span><span style="color: #ff4500">$ID</span><span style="color: #8b0000">"</span>
<span style="color: #000000">    </span><span style="color: #ff4500">$TableQuery</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SelectColumns </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #ff4500">$list</span>
<span style="color: #000000">         </span><span style="color: #006400">#Execute the query.</span>
<span style="color: #000000">    </span><span style="color: #ff4500">$Query</span><span style="color: #000000"> </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #ff4500">$table</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CloudTable</span><span style="color: #a9a9a9">.</span><span style="color: #000000">ExecuteQuery(</span><span style="color: #ff4500">$TableQuery</span><span style="color: #000000">)          </span><span style="color: #006400">#Exectute the query against the database</span>
<span style="color: #000000">    </span><span style="color: #ff4500">$DatabaseConnection</span><span style="color: #a9a9a9">.</span><span style="color: #000000">ConnectionString </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #8b0000">"Server=</span><span style="color: #ff4500">$ServerName</span><span style="color: #8b0000">; Database=</span><span style="color: #ff4500">$DatabaseName</span><span style="color: #8b0000">; User ID=</span><span style="color: #ff4500">$UserId</span><span style="color: #8b0000">; Password=</span><span style="color: #ff4500">$Password</span><span style="color: #8b0000">;Connection Timeout=300"</span>
<span style="color: #000000">    </span><span style="color: #ff4500">$DatabaseConnection</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Open();     </span><span style="color: #006400"># Create command for a specific database $DBName</span>
<span style="color: #000000">    </span><span style="color: #ff4500">$DatabaseCommand</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Connection </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #ff4500">$DatabaseConnection</span>
<span style="color: #000000">    </span><span style="color: #ff4500">$DatabaseCommand</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CommandText </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #ff4500">$Query</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Properties</span><span style="color: #a9a9a9">[</span><span style="color: #8b0000">"Query"</span><span style="color: #a9a9a9">].</span><span style="color: #000000">StringValue          </span><span style="color: #ff4500">$NonQueryResult</span><span style="color: #000000"> </span><span style="color: #a9a9a9">=</span><span style="color: #000000"> </span><span style="color: #ff4500">$DatabaseCommand</span><span style="color: #a9a9a9">.</span><span style="color: #000000">ExecuteNonQuery()                                              </span><span style="color: #006400"># Close connection</span>
<span style="color: #000000">    </span><span style="color: #ff4500">$DatabaseConnection</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Close()     </span><span style="color: #006400">#Write-Output $Query.Properties["Query"].StringValue</span>
<span style="color: #000000">          </span><span style="color: #006400"># Sleep for 250 miliseconds between loops </span>
<span style="color: #000000">    </span><span style="color: #0000ff">Start-Sleep</span><span style="color: #000000"> </span><span style="color: #000080">-Milliseconds</span><span style="color: #000000"> </span><span style="color: #800080">250</span><span style="color: #000000">    }
}
}</span></pre>
&nbsp;

I’ve tried to make the runbook as dynamic as possible, I have specified several parameters in the “param” section.
<ul>
 	<li>$SqlServerName = The fully qualified name of your logical SQL Server</li>
 	<li>$SqlDatabaseName = The name of your database, in my example AdventureWorks2014</li>
 	<li>$Credential = This is the Azure Credential that you have just created to authenticate against your logical SQL Server</li>
 	<li>$StorageAccount = The storage account that has been used for your Azure Table</li>
 	<li>$StorageKey = The Storage Account Key to connect to your storage account</li>
</ul>
In the while loop, I’m first picking a random number and select the query with the ID that is equal to the random number.
The result is stored in the $query parameter. Secondly, I open a connection to my database and execute the query that I have just stored in the $query parameter

After the runbook creation, you can test it. Click on the edit button and click Test.

<a href="https://msdnshared.blob.core.windows.net/media/2016/01/image60.png"><img width="223" height="529" title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/01/image_thumb58.png" border="0" /></a>

If your tests are OK (you should see the ID’s in the output screen), you can Publish your runbook by clicking the Publish button.
<h4>Launch the SQL Workload</h4>
To launch the workload, just start the runbook.

<a href="https://msdnshared.blob.core.windows.net/media/2016/01/image35.png"><img width="193" height="120" title="image" style="padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px;border-width: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/01/image_thumb35.png" border="0" /></a>

As a result, you will notice that a job is created. Verify the errors and warnings in case you encounter issues with the load

<a href="https://msdnshared.blob.core.windows.net/media/2016/01/image61.png"><img width="455" height="374" title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/01/image_thumb59.png" border="0" /></a>

The job can run for maximum 9 hours. We put a limit on this. If the runbook restarts from the same checkpoint or from the beginning of the runbook three consecutive times, it will be terminated with a status of Failed, waiting for resources. This is to protect from runbooks running indefinitely without completing. More information can be found on <a target="_blank" href="https://azure.microsoft.com/en-us/documentation/articles/automation-runbook-execution/">Runbook execution in Azure Automation</a>

<a href="https://msdnshared.blob.core.windows.net/media/2016/01/image62.png"><img width="616" height="162" title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/01/image_thumb60.png" border="0" /></a>

If you want a continues load, I suggest to created a schedule for the runbook that is launched every 12 hours.

Also make sure that you select the Basic pricing tier of your Automation account. If you choose Free, you only get 500 job minutes, which means that after these minutes, your job will stop.

<a href="https://msdnshared.blob.core.windows.net/media/2016/01/image63.png"><img width="336" height="391" title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/01/image_thumb61.png" border="0" /></a>
<h3>Monitoring the workload</h3>
You can verify the workload by using some of the monitoring charts in the portal. If you select the database in the Azure Portal, you can see an overview of the average DTU usage of the past hour. If you click on the “Edit” link, you can modify the graph style and add multiple counters like Data IO Percentage, CPU Percentage, …

<a href="https://msdnshared.blob.core.windows.net/media/2016/01/image64.png"><img width="337" height="240" title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/01/image_thumb62.png" border="0" /></a> <a href="https://msdnshared.blob.core.windows.net/media/2016/01/image65.png"><img width="219" height="399" title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/01/image_thumb63.png" border="0" /></a>

If you want to have a more detailed overview, you can use the new functionality called <a target="_blank" href="https://azure.microsoft.com/sv-se/documentation/articles/sql-database-query-performance/">Query Performance Insight</a>. If you want to start using the insight, you just have to switch on the Query Store on the Azure Database.

Last but not least, most of the DMV’s are also working on the Azure Database. With the query below, you can determine the most consuming queries of your workload

&nbsp;
<h3>Conclusion</h3>
If you run the SQL Workload for a few days, you will notice that the Index Advisor will give you index recommendations!

<a href="https://msdnshared.blob.core.windows.net/media/2016/01/image66.png"><img width="788" height="249" title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/01/image_thumb64.png" border="0" /></a>]]></content:encoded>
    </item>
  </channel>
</rss>