<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>MSSQL Tiger Team</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/sql_server_team/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/sql_server_team/feed.xml</link>
    <description>This is the official web log for the SQL Server engineering team – we focus on learning customer workloads running on SQL Server, integrating that feedback to enhance the product, and provide guidance on using SQL Server to solve customers&amp;#039; business challenges.</description>
    <lastBuildDate>Wed, 08 May 2019 22:49:13 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>We have moved!</title>
      <link>https://docs.microsoft.com/archive/blogs/sql_server_team/we-have-moved</link>
      <pubDate>Fri, 29 Mar 2019 11:01:28 GMT</pubDate>
      <dc:creator><![CDATA[Pedro Lopes (PL)]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sql_server_team/?p=8205</guid>
      <description><![CDATA[Thanks for visiting! This blog has now been migrated...]]></description>
      <content:encoded><![CDATA[Thanks for visiting! This blog has now been migrated to:

<a href="https://techcommunity.microsoft.com/t5/SQL-Server/bg-p/SQLServer/label-name/SQLServerTiger">https://techcommunity.microsoft.com/t5/SQL-Server/bg-p/SQLServer/label-name/SQLServerTiger</a>

&nbsp;

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>We are moving!</title>
      <link>https://docs.microsoft.com/archive/blogs/sql_server_team/we-are-moving</link>
      <pubDate>Mon, 04 Mar 2019 10:22:38 GMT</pubDate>
      <dc:creator><![CDATA[Pam Lahoud]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sql_server_team/?p=8185</guid>
      <description><![CDATA[This blog is in the process of being migrated to one of the new consolidated SQL Server and Azure...]]></description>
      <content:encoded><![CDATA[This blog is in the process of being migrated to one of the new consolidated <a href="https://techcommunity.microsoft.com/t5/SQL-Server/ct-p/SQL-Server">SQL Server</a> and <a href="https://techcommunity.microsoft.com/t5/Azure-SQL-Database/bg-p/Azure-SQL-Database">Azure SQL Database</a> blogs on the <a href="https://techcommunity.microsoft.com/">Microsoft TechCommunity</a> website. Once the migration is complete, we will post the new URL along with instructions for how to navigate the new blog and update your RSS feeds. Until then, feel free to keep reading here, but keep in mind that any comments that are added may not make it over to the new blog. You will be able to re-post them there once we are live. Stay tuned and see you on the new site soon!]]></content:encoded>
    </item>
    <item>
      <title>Let’s talk about trace flags</title>
      <link>https://docs.microsoft.com/archive/blogs/sql_server_team/lets-talk-about-trace-flags</link>
      <pubDate>Mon, 14 Jan 2019 08:00:53 GMT</pubDate>
      <dc:creator><![CDATA[Pam Lahoud]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sql_server_team/?p=8165</guid>
      <description><![CDATA[One of the most confusing aspects of SQL Server configuration is often trace flags. There are lots...]]></description>
      <content:encoded><![CDATA[One of the most confusing aspects of SQL Server configuration is often trace flags. There are lots of trace flags out there, and while many of them are <a href="https://aka.ms/traceflags">documented</a>, when to use them and when not to is not always clear. The primary reason for this post is to introduce a new article from Microsoft Support that provides guidance on trace flags and other configurations which may help high-end SQL Servers perform better:

<em>Recommended updates and configuration options for SQL Server 2017 and 2016 with high-performance workloads</em>
<a href="https://support.microsoft.com/kb/4465518">https://support.microsoft.com/kb/4465518</a>

The article was published this past fall and is an update of an older article with which you may already be familiar:

<em>Recommended updates and configuration options for SQL Server 2012 and SQL Server 2014 with high-performance workloads</em>
<a href="https://support.microsoft.com/kb/2964518">https://support.microsoft.com/kb/2964518</a>

Microsoft Support has provided these articles to help guide customers toward configuration options that both improve performance, but also help to avoid known issues that present themselves when the server is running on big iron (large memory and many CPUs) and/or is under heavy load.

You may be asking yourself, if these trace flags provide a benefit, why aren't they just the default behavior? In a lot of cases, we're asking ourselves the same thing <span style="font-family: Segoe UI Emoji">😊</span> If you've read both the articles above, you may have noticed that the list of recommended trace flags for SQL Server 2016 and 2017 is much smaller than the list for 2012 and 2014. This is because starting with SQL Server 2016, many of the trace flags that were introduced to solve problems in earlier versions just became the default behavior.
<h2>So why do we even have trace flags to begin with?</h2>
Some trace flags are used to <strong>enable enhanced debugging features</strong> such as additional logging, memory dumps etc. and are used only when you are working with Microsoft Support to provide additional data for troubleshooting. These trace flags are not ones you want to leave turned on in a production system as they may have a negative impact on your workload. An example of one of these flags would be TF 2551 which is used to trigger a <a href="https://support.microsoft.com/kb/917825">filtered memory dump</a> whenever there is an exception or assertion in the SQL Server process. These trace flags are only used for a short period of time and typically only at the recommendation of Microsoft Support, so they will likely always be around.

Other trace flags are used to <strong>alter the behavior of the server</strong> in other ways, such as to turn a feature ON or OFF or change the way the database engine manages resources. One example of this type of trace flag is 7752 which was introduced as a knob for something that is default behavior in Azure SQL DB. In a SQL Server (on-prem or IaaS) database that is undergoing recovery and has Query Store (QDS) enabled, user queries will be blocked until all the data required for QDS to start is loaded. This ensures QDS doesn't miss any queries that are executed in that database. In some cases, this can take a long time to complete and you'll see sessions with a wait type of QDS_LOADDB until the QDS becomes available. Turning on TF 7752 makes this process asynchronous so that user queries can proceed while the QDS starts. It's not something we want to make the default behavior in general because it means that some query executions won't be captured by QDS, but it's a tradeoff you might be willing to make in order to reduce the time it takes for a database to become available upon restart or failover. This is the sort of trace flag that we are trying to incorporate into the product in some other way, such as to provide a database-scoped configuration. Moving forward, we hope not to introduce any new trace flags like this, and over time the number of flags of this type should approach zero.

A subset of the above category is what many folks call the "benchmark specials" – trace flags that alter or disable database engine behavior that is normally desirable, but perhaps not absolutely required if you want lightening fast performance. This would be things like trace flag 661 that disables ghost record cleanup, or one of several flags that disable ring buffers used for monitoring and diagnostic purposes. For the most part, these flags are not ones that you want to run in production because they turn off features that are required for the maintenance and manageability of your server. If you really need lightening fast performance though, and you're willing to make the trade-off of manageability for speed, these are available and documented <a href="https://support.microsoft.com/kb/920093/">here</a>. Most of these flags don't make sense to add to the product, but there are a few that have become useful in wider scenarios and are recommended for certain workloads. One flag like this is trace flag 834. This flag turns on large-page memory allocations for the buffer pool, which can be helpful for data warehouse-type workloads. There are some caveats to turning this flag on however, so be sure to review the documentation before considering it. This is one that is also documented in the two KB articles referenced at the top of this blog.

The last reason for trace flags is to <strong>introduce new behavior or change existing behavior in an in-market release of SQL Server</strong> (i.e. a Cumulative Update). We know our customers find that installing updates can be disruptive, and there are many risk-averse customers who are reluctant to apply any non-security updates at all. For the past several versions of SQL Server we have worked hard to make updates as seamless as possible, and this includes keeping any potential behavior changes to a minimum. As <a href="https://twitter.com/SQLPedro">Pedro</a> likes to say, "backward compatibility is the unsung hero feature of SQL Server" <span style="font-family: Segoe UI Emoji">😊</span> To that end, any change we make to an in-market release of SQL Server that has the potential to impact performance or change the behavior of your application, be it an improvement or a bug fix, will be gated by a trace flag (or compatibility level – <a href="https://aka.ms/dbcompat">that's another story</a>). The most common trace flag like this is 4199. This is a very important flag, and one that's going to be around for a while so it's worth talking about in some detail.

Fixes to the query optimizer fall under the category of behavior changes that have the potential to impact performance. In many cases, the impact should be positive, but sometimes there are edge cases where they can have a negative impact, so it's not something we want to throw into a cumulative update by default. For this reason, all the fixes that were made to the optimizer between SQL Server 7.0 and SQL Server 2014 were gated by a trace flag. Up until SQL Server 2005 SP3, each one would have to be enabled individually, but in this release, they were rolled up under TF 4199. If you're running one of these versions of SQL Server and you don't have this trace flag turned on, you're missing out on 20 some-odd years of query optimizer fixes that may benefit your workload.

Starting with SQL Server 2016, all the fixes from SQL Server 7.0 up to SQL Server 2016 RTM were rolled into the engine by default (when running with 130 compatibility level), but the changes that were released <span style="text-decoration: underline">AFTER</span> SQL Server 2016 RTM are still gated by TF 4199. This was also the case with SQL Server 2017 RTM and will continue to be the practice moving forward, all the optimizer fixes will be rolled into the engine at RTM and this becomes the baseline optimizer behavior for that compatibility level (even if you're running on a later version of the database engine). When you have 4199 enabled, all the optimizer fixes available in the current build that are applicable to the current database compatibility level will be enabled. Incidentally, this behavior can also be controlled at the database level using the QUERY_OPTIMIZER_HOTFIXES <a href="https://docs.microsoft.com/sql/t-sql/statements/alter-database-scoped-configuration-transact-sql">database scoped configuration</a> option and at the query level using the <span style="color: black"><span style="background-color: white">USE HINT 'ENABLE_QUERY_OPTIMIZER_HOTFIXES' <a href="https://docs.microsoft.com/sql/t-sql/queries/hints-transact-sql-query"></a></span>query hint</span>, although the trace flag is needed if you want to set this at the server level.

As you modernize your databases, you should find that the configuration experience for SQL Server gets simpler and more intuitive. While there will likely always be some trace flags, we expect their use to be limited in scope, and any trace flags that are recommended by Microsoft for production use will be thoroughly documented. In the meantime, be sure to reference the articles above any time you build and configure a new SQL Server. We will try to keep these updated whenever new support trends emerge that indicate a trace flag or other configuration setting should be widely recommended for Tier-1 workloads.]]></content:encoded>
    </item>
    <item>
      <title>Replica Failover within the Secondary Availability Group in a Distributed Availability Group</title>
      <link>https://docs.microsoft.com/archive/blogs/sql_server_team/replica-failover-within-the-secondary-availability-group-in-a-distributed-availability-group</link>
      <pubDate>Wed, 09 Jan 2019 13:27:38 GMT</pubDate>
      <dc:creator><![CDATA[Pam Lahoud]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sql_server_team/?p=7805</guid>
      <description><![CDATA[A distributed availability group (distributed AG) is a special type of availability group that spans...]]></description>
      <content:encoded><![CDATA[A <a href="https://docs.microsoft.com/en-us/sql/database-engine/availability-groups/windows/distributed-availability-groups?view=sql-server-2017">distributed availability group</a> (distributed AG) is a special type of availability group that spans two availability groups. This blog will clarify some issues regarding failover in a distributed AG, specifically demonstrates distributed AG resiliency from data loss despite the synchronizing state between the availability groups.

A simple distributed AG ‘TIWENDAG’ is created for relevant tests that will be addressed later in this blog. The structure of ‘TIWENDAG’ is illustrated by the following diagram. ‘TIWENAG1’ is the primary AG of distributed AG ‘TIWENDAG’, with ‘TIWENVM1’ as the primary replica and ‘TIWENVM2’ as the secondary replica. ‘TIWENAG2’ is the secondary AG of the distributed AG, with ‘TIWENVM3’ as the primary replica and ‘TIWENVM4’ as the secondary replica.

<img width="832" height="437" class="alignnone size-full wp-image-8105" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/p11.png" />

Automatic failover of the two availability groups defined in the distributed AG is supported. For example, if “automatic” is specified for failover mode in availability group TIWENAG1, then automatic failover can occur between TIWENAG1 (primary) and TIWENAG2 (synchronous secondary) in the event that TIWENAG1 goes down. Similarly, in availability group TIWENAG2, in the event TIWENVM3 (primary) goes down, it can automatically failover to TIWENVM4 (synchronous secondary).

the primary replica in the AG (no matter whether the AG is part of a distributed AG) will automatically failover to a synchronous secondary replica when the primary replica goes down.

If the primary replica on the secondary AG (also known as the “forwarder”) is lost and causes automatic failover to happen or manual failover is performed in the secondary AG in a distributed AG, there will be no data loss if the following conditions are met:
<ul>
 	<li>The primary replica on the primary AG (which is usually referred to as "global primary") is successfully synchronizing with the forwarder replica in the secondary AG over their database mirroring endpoints.</li>
 	<li>The forwarder replica in the secondary AG is successfully synchronizing with the secondary replica in the secondary AG over their database mirroring endpoints.</li>
</ul>
Assume that the hardened LSN on the global primary, “TIWENVM1”, is 10:15:1. The secondary replica of the primary AG, “TIWENVM2”, is synchronous, and its hardened LSN is also 10:15:1. For the secondary AG, between the primary AG and the forwarder, synchronization mode is asynchronous, and the hardened LSN of the forwarder, “TIWENVM3”, is 10:12:1. The secondary replica of the secondary AG, “TIWENVM4”, is not yet synchronized and its hardened LSN is 10:10:1. Globally across the two AGs in the distributed AG, replica “TIWENVM4” has the smallest value of hardened LSN, truncation LSN on the global primary won’t go beyond this smallest value. In the event that “TIWENVM3” is lost and “TIWENVM4” becomes the new forwarder, it will be able to synchronize with the primary AG.

<img width="643" height="115" class="alignnone size-full wp-image-8115" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/p2.png" />

The reason for this is that when the transaction logs are backed up, only the logs that have been applied to all the replicas in the distributed AG (including the replicas in both AGs) will be truncated. The following table provides an example of how the transaction logs will be truncated in a distributed AG, using the test environment described at the beginning of this post.

This scenario can be easily demonstrated. The steps are as following:
<ol>
 	<li>Record the current truncation_lsn and last hardened LSN of each replica.</li>
 	<li>Modify the database. Here an <code>INSERT</code> query is executed 10 times on the “test” database.</li>
 	<li>Verify that the last hardened LSN of each replica grows by the same number.</li>
 	<li>Do a transaction logs back up on the “test” database on the global primary.</li>
 	<li>Verify current truncation_lsn and last hardened LSN .</li>
 	<li>Suspend data movement on the secondary replica on the secondary AG.</li>
 	<li>Repeat 2-5.</li>
</ol>
The following screenshots record a complete repro of the scenario.

&nbsp;
<h5><strong>Step1 -</strong></h5>
DMVs used in this step:

<code>USE test</code>

<code>SELECT COUNT(*) AS '# of transaction logs' FROM fn_dblog(null, null)</code>

<code>SELECT database_id,</code>
<code>       group_id,</code>
<code>       replica_id,</code>
<code>       is_local,</code>
<code>       is_primary_replica,</code>
<code>       truncation_lsn,</code>
<code>       last_hardened_lsn</code>
<code>FROM sys.dm_hadr_database_replica_states</code>
<code>WHERE database_id=6 AND is_local=1</code>

<code>SELECT replica_id, replica_server_name</code>
<code>FROM sys.availability_replicas</code>
<code>WHERE replica_id=</code>
<code>      (SELECT replica_id FROM sys.dm_hadr_database_replica_states WHERE database_id=6 AND is_local=1)</code>

<code>SELECT COUNT(*) AS '# of entries in testt1 table' FROM testt1</code>

Results from the four replicas :

Primary replica on primary AG (global primary):

<img width="926" height="178" class="alignnone size-full wp-image-7825" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/3.png" />

Secondary replica on primary AG:

<img width="931" height="184" class="alignnone size-full wp-image-7835" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/4.png" />

Primary replica on secondary AG (forwarder):

<img width="934" height="184" class="alignnone size-full wp-image-7845" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/5.png" />

Secondary replica on secondary AG:

<img width="928" height="181" class="alignnone size-full wp-image-7855" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/6.png" />

If all the replicas are synchronized, all the replicas should have the same number of transaction logs as well as the same truncation_lsn as in the test environment shown in the screenshots above.
<h5><strong>Step 2 -</strong></h5>
Execute an <code>INSERT</code> clause 10 times.

<code>INSERT INTO testt1 (NAME, ID) VALUES ('John Smith', 1)
GO</code>
<h5><strong>Step 3 -</strong></h5>
Primary replica on primary AG (global primary):

<img width="353" height="136" class="alignnone size-full wp-image-7865" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/31.png" />

Secondary replica on primary AG:

<img width="356" height="141" class="alignnone size-full wp-image-7875" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/32.png" />

Primary replica on secondary AG (forwarder):

<img width="362" height="139" class="alignnone size-full wp-image-7885" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/33.png" />

Secondary replica on secondary AG:

<img width="354" height="140" class="alignnone size-full wp-image-7895" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/34.png" />

The size of transaction logs grows due to the <code>INSERT</code> executions. The increase of entries in the ‘test’ database also reflects that 10 rows are inserted into the table.
<h4></h4>
<h5><strong>Step 4 -</strong></h5>
Perform a transaction log backup on the global primary.

<img width="912" height="669" class="alignnone size-full wp-image-7905" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/41.png" />

&nbsp;
<h5><strong>Step 5 -</strong></h5>
Primary replica on primary AG (global primary):

<img width="934" height="181" class="alignnone size-full wp-image-7915" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/51.png" />

Secondary replica on primary AG:

<img width="933" height="181" class="alignnone size-full wp-image-7925" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/52.png" />

Primary replica on secondary AG (forwarder):

<img width="939" height="183" class="alignnone size-full wp-image-7935" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/53.png" />

Secondary replica on secondary AG:

<img width="929" height="183" class="alignnone size-full wp-image-7945" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/54.png" />

Truncation_lsn of each replica should grow to the current lsn, and the number of transaction logs should shrink by the same size as the t-logs have been truncated.

&nbsp;
<h5><strong>Step 6 -</strong></h5>
Suspend data movement of ‘test’ database on the secondary replica on the secondary AG.

<img width="351" height="231" class="alignnone size-full wp-image-7955" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/61.png" />

&nbsp;
<h5><strong>Step 7 -</strong></h5>
After repeating step 2 and 3, we can see that except for the secondary replica on the secondary AG (TIWENVM4), the ‘test’ database on all other three replicas are modified again and another 10 entries are inserted into the table. The database on secondary replica on the secondary AG is not updated because the data movement has been suspended.

Primary replica on primary AG (global primary):

<img width="355" height="136" class="alignnone size-full wp-image-7965" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/71.png" />

Secondary replica on primary AG:

<img width="357" height="139" class="alignnone size-full wp-image-7975" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/72.png" />

Primary replica on secondary AG (forwarder):

<img width="361" height="138" class="alignnone size-full wp-image-7985" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/73.png" />

Secondary replica on secondary AG:

<img width="357" height="138" class="alignnone size-full wp-image-7995" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/74.png" />

The results from repeating step 4 and 5 are shown below.

Primary replica on primary AG (global primary):

<img width="934" height="180" class="alignnone size-full wp-image-8005" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/75.png" />

Secondary replica on primary AG:

<img width="935" height="184" class="alignnone size-full wp-image-8015" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/76.png" />

Primary replica on secondary AG (forwarder):

<img width="936" height="183" class="alignnone size-full wp-image-8025" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/77.png" />

Secondary replica on secondary AG:

<img width="930" height="183" class="alignnone size-full wp-image-8035" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/78.png" />

Note that the newly generated transaction logs were truncated on the secondary replica on the primary AG, but the truncation_lsn of the primary replica on the primary didn’t change after 10 new rows were inserted into the database and executing transaction logs back up. As mentioned earlier, this is because the secondary replica on the secondary AG of the distributed AG (TIWENVM4) is not yet synchronized and thus has not successfully applied the new transaction logs generated by the <code>INSERT</code> queries.

The global primary of a distributed AG only truncates logs to the least LSN among all the replicas in the distributed AG. This logic guarantees that there’ll be no data loss when the forwarder got lost even when the secondary replica on the secondary AG has not fully synchronized with the forwarder, as long as the global primary is in a healthy state and can communicate with the secondary replica on the secondary AG properly.

To simulate the scenario mentioned above, we shut down the network of the primary replica on the secondary AG (TIWENVM3) so that it becomes unavailable before we resume the data movement on the secondary replica on the secondary AG (TIWENVM4).

<img width="709" height="262" class="alignnone size-full wp-image-8085" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/failed-to-retrive-data.png" />

After the data movement of ‘test’ database on TIWENVM4 is resumed, the secondary AG (TIWENAG2) is now in a resolving state because the current primary replica on TIWENAG2, TIWENVM3, fails to be connected. To fix this issue, a failover needs to be performed. Under the scenario when in the secondary AG of a distributed AG, the forwarder is not available, the only failover option to the secondary replica of the secondary AG is <code>FORCE_FAILOVER_ALLOW_DATA_LOSS</code>.

<code>ALTER AVAILABILITY GROUP TIWENAG2 FORCE_FAILOVER_ALLOW_DATA_LOSS</code>

After performing failover with <code>FORCE_FAILOVER_ALLOW_DATA_LOSS</code> on the secondary replica on the secondary AG (TIWENVM4), the database is synced even though the previous forwarder is currently unavailable, as the global primary keeps track of the unsynchronized part of transaction logs of the secondary replica on the secondary AG.

<img width="926" height="181" class="alignnone size-full wp-image-8095" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/no-data-loss-vm4.png" />

In this scenario, though the only failover option is <code>FORCE_FAILOVER_ALLOW_DATA_LOSS</code>, there’s no data loss during the failover.

One thing worth notice is that after <code>FORCE_FAILOVER_ALLOW_DATA_LOSS</code> and the previous primary replica (in this case, TIWENVM3) is brought back, data movement will not resume automatically and needs to be resumed manually. This behavior is by design and not limited to the distributed AG scenario but applies whenever failover with <code>FORCE_FAILOVER_ALLOW_DATA_LOSS</code> is performed. This is because there might be difference and even conflicts between the previous primary replica and the new primary replica, and user needs to manually choose which version to keep.

<img width="355" height="267" class="alignnone size-full wp-image-8125" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/resume-data-movement.png" />

After resuming data movement on TIWENVM3, all replicas on the distributed AG are synchronized and the transaction logs get truncated to the same point.

Primary replica on primary AG (global primary):

<img width="932" height="179" class="alignnone size-full wp-image-8045" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/e1.png" />

Secondary replica on primary AG:

<img width="935" height="181" class="alignnone size-full wp-image-8055" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/e2.png" />

(New) Secondary replica on secondary AG (former forwarder):

<img width="937" height="183" class="alignnone size-full wp-image-8065" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/e3.png" />

(New) Primary replica on secondary AG (new forwarder):

<img width="929" height="183" class="alignnone size-full wp-image-8075" alt="" src="https://msdnshared.blob.core.windows.net/media/2019/01/e4.png" />

It needs to be clarified that though under this scenario, <code>FORCE_FAILOVER_ALLOW_DATA_LOSS</code> in the secondary AG doesn’t cause data loss, it’s not guaranteed that there’ll be no data loss when using this option to perform failover in a distributed AG. For example, if the primary AG is lost, there might be data loss when a force failover is performed in the secondary AG. This behavior is expected, and the cases that might cause data loss are not limited to this example.]]></content:encoded>
    </item>
    <item>
      <title>SQL Server 2017 on Linux: Support for third-party AD providers</title>
      <link>https://docs.microsoft.com/archive/blogs/sql_server_team/sql-server-2017-on-linux-support-for-third-party-ad-providers</link>
      <pubDate>Mon, 26 Nov 2018 09:30:44 GMT</pubDate>
      <dc:creator><![CDATA[Pam Lahoud]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sql_server_team/?p=7745</guid>
      <description><![CDATA[In the past, SQL Server on Linux has required SSSD to be configured for AD Authentication to work....]]></description>
      <content:encoded><![CDATA[In the past, SQL Server on Linux has required SSSD to be configured for AD Authentication to work. SSSD is a very powerful service which provides support AD authentication and integration. However, there are some third-party AD providers (such as Centrify, PBIS, and VAS) which provide additional value-added services (such as auditing) on top of basic AD authentication. These third-party AD providers do not configure SSSD when joining the AD domain.

&nbsp;

There are many customers which depend on these third-party AD providers to provide single “trusted zone” for all users to access resources regardless of the host OS of said resources. In today’s hybrid environments which uses Windows server, Linux servers and Windows AD to provide authentication, ease of configuration and audit capability among others, are often highly preferred. Listening to the demand from such customers, SQL Server now supports AD authentication without SSSD.

&nbsp;

To support these third-party AD providers which do not configure SSSD, SQL Server performs its own LDAP queries when looking up AD accounts. For this to work successfully, several extra configuration checks must be done, and these can be found here: <u><a href="https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-active-directory-third-party-providers?view=sql-server-2017">https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-active-directory-third-party-providers?view=sql-server-2017</a></u>. This functionality was made available in SQL Server 2017 CU10 first. But it is highly recommended to use it with SQL Server 2017 CU12 onwards.

&nbsp;

Additionally, if your domain controller supports LDAPS, you can force all connections from SQL Server to the domain controllers to be over LDAPS. To check your client can contact the domain controller over ldaps, run the following bash command, “ldapsearch -H ldaps://contoso.com:3269”. To set SQL Server to only use LDAPS, run the following:
<ul>
 	<li>sudo mssql-conf set network.disablesssd true</li>
 	<li>sudo mssql-conf set network.forceldaps true</li>
 	<li>systemctl restart mssql-server</li>
</ul>
Tejas Shah - Senior Program Manager

Dylan Gray - Senior Software Engineer]]></content:encoded>
    </item>
    <item>
      <title>Failover Detection Utility - Availability Group Failover Analysis Made Easy</title>
      <link>https://docs.microsoft.com/archive/blogs/sql_server_team/failover-detection-utility-availability-group-failover-analysis-made-easy</link>
      <pubDate>Mon, 19 Nov 2018 12:25:01 GMT</pubDate>
      <dc:creator><![CDATA[Pam Lahoud]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sql_server_team/?p=7725</guid>
      <description><![CDATA[To analyze the root cause for the failover of an Availability group, users are required to perform...]]></description>
      <content:encoded><![CDATA[To analyze the root cause for the failover of an Availability group, users are required to perform coordinated analysis of various logs including the Cluster Logs, SQL Error Logs, and the Availability groups extended events logs. This coordinated analysis of the logs can be difficult and requires extensive knowledge of the internals and the various logs associated with Availability Groups. The failover detection utility is meant to make this analysis easier and provide a quick root cause analysis for the unexpected failovers and/or failed failovers. The failover detection utility currently only supports analysis of Availability groups on Windows.

<span style="text-decoration: underline"><strong>Failover Detection Utility</strong></span>

The failover detection utility can be downloaded <a href="https://github.com/Microsoft/tigertoolbox/tree/master/Always-On/FailoverDetection">here</a>. The download consists of the following files.
<ol>
 	<li>FailoverDetector.exe – The Failover analysis utility.</li>
 	<li>Configuration.json – The configuration file for the failover analysis utility. The file consists of the following fields.
{
"Data Source Path": "F:\\DataLocation\\Data",
"Health Level": 3,
"Instances":
[
"Replica1",
"Replica2",
"Replica3"
]
}
<em><strong>Data Source Path</strong> </em>– Location for the Logs from the different replicas in the Availability Group.
<em><strong>Health Level</strong> </em>– The failover policy level configured for the availability group. More information on the different failover conditions can be found here.
<em><strong>Instance</strong></em> – The list of replicas in the availability groups.</li>
 	<li>Supporting DLL’s – Supporting DLLs for the Failover analysis utility.</li>
 	<li>Data and Reports Folders – The Data and Analysis reports folders.</li>
</ol>
<span style="text-decoration: underline"><strong>Preparing for Failover Analysis with the Failover Detection Utility</strong></span>

The first step in using the utility is to configure the configuration.json file to include the location of the data files and the details of the availability group for which analysis is being done. For a correct analysis, all replicas in the availability groups needs to be listed in the configuration file.

The next step is to capture the various logs from each of the replicas and add those under the data folder. The following files are required for the analysis.
<ul>
 	<li>SQL error logs</li>
 	<li>Always On Availability Groups Extended Event Logs</li>
 	<li>System Health Extended Event Logs</li>
 	<li>System log</li>
 	<li>Windows cluster log</li>
</ul>
The first three categories of logs can be found in the LOG folder of the SQL instance installation path. For example, if you have a SQL Server 2017 instance named "SQL17RTM01" and If the installation path is on C drive, you will find the above three categories of logs under "C:\Program Files\Microsoft SQL Server\MSSQL14.SQL17RTM01\MSSQL\Log", and copy all AlwaysOn XEvent, System Health XEvent and SQL ERRORLOG files.

The last two categories of logs can be found. You can use commands mentioned below to collect these logs.
<p style="margin-left: 36pt"><em>Get-ClusterLog -Node $server.ComputerNamePhysicalNetBIOS -Destination $server.ErrorLogPath</em></p>
<p style="margin-left: 36pt"><em>Get-Eventlog -ComputerName $server.ComputerNamePhysicalNetBIOS -LogName System | Export-CSV -Path $SystemLogExportPath</em></p>
<span style="text-decoration: underline"><strong>Organizing the files
</strong></span>

The log files collected in the previous step should be placed in a folder with correct subfolder structure. This folder should be the folder path specified in the "Data Source Path" section of the configuration file "Configuration.json". The following is an example of the subfolder structure, assuming there are two replicas (instances) in the AG. One is "Replica1" and another one is "Replica2".
<p style="margin-left: 24pt">¦ +---Data</p>
<p style="margin-left: 24pt">¦ ¦</p>
<p style="margin-left: 24pt">¦ ¦</p>
<p style="margin-left: 24pt">¦ +---Replica1</p>
<p style="margin-left: 24pt">¦ ¦ AlwaysOn_health_0_131532583880140000.xel</p>
<p style="margin-left: 24pt">¦ ¦ AlwaysOn_health_0_131532634780070000.xel</p>
<p style="margin-left: 24pt">¦ ¦ AlwaysOn_health_0_131532680183890000.xel</p>
<p style="margin-left: 24pt">¦ ¦ AlwaysOn_health_0_131532701164380000.xel</p>
<p style="margin-left: 24pt">¦ ¦ ERRORLOG</p>
<p style="margin-left: 24pt">¦ ¦ ERRORLOG.1</p>
<p style="margin-left: 24pt">¦ ¦ ERRORLOG.2</p>
<p style="margin-left: 24pt">¦ ¦ ERRORLOG.3</p>
<p style="margin-left: 24pt">¦ ¦ SQLDUMPER_ERRORLOG.log</p>
<p style="margin-left: 24pt">¦ ¦ system_health_0_131532583879830000.xel</p>
<p style="margin-left: 24pt">¦ ¦ system_health_0_131532634779760000.xel</p>
<p style="margin-left: 24pt">¦ ¦ system_health_0_131532680183430000.xel</p>
<p style="margin-left: 24pt">¦ ¦ system_health_0_131532701164070000.xel</p>
<p style="margin-left: 24pt">¦ ¦ Replica1_system.log</p>
<p style="margin-left: 24pt">¦ ¦ Replica1_cluster.log</p>
<p style="margin-left: 24pt">¦ ¦</p>
<p style="margin-left: 24pt">¦ +---Replica2</p>
<p style="margin-left: 24pt">¦ AlwaysOn_health_0_131532571347210000.xel</p>
<p style="margin-left: 24pt">¦ AlwaysOn_health_0_131532578226200000.xel</p>
<p style="margin-left: 24pt">¦ AlwaysOn_health_0_131532586348180000.xel</p>
<p style="margin-left: 24pt">¦ AlwaysOn_health_0_131532725682240000.xel</p>
<p style="margin-left: 24pt">¦ ERRORLOG</p>
<p style="margin-left: 24pt">¦ ERRORLOG.1</p>
<p style="margin-left: 24pt">¦ ERRORLOG.2</p>
<p style="margin-left: 24pt">¦ ERRORLOG.3</p>
<p style="margin-left: 24pt">¦ ERRORLOG.4</p>
<p style="margin-left: 24pt">¦ ERRORLOG.5</p>
<p style="margin-left: 24pt">¦ ERRORLOG.6</p>
<p style="margin-left: 24pt">¦ system_health_0_131532571346430000.xel</p>
<p style="margin-left: 24pt">¦ system_health_0_131532578225950000.xel</p>
<p style="margin-left: 24pt">¦ system_health_0_131532586347860000.xel</p>
<p style="margin-left: 24pt">¦ system_health_0_131532725681930000.xel</p>
<p style="margin-left: 24pt">¦ Replica2_system.csv</p>
<p style="margin-left: 24pt">¦ Replica2_cluster.log</p>
<span style="text-decoration: underline"><strong>Executing the Utility
</strong></span>

The FailoverDetection.exe can be executed with the following flags (or default mode without any flags)

<strong>Default Mode (No execution flags defined) -</strong> In the default mode, where no parameters are passed to the utility, the analysis tool will load the configuration file, copy log data from data source path to local workspace data folder, examine the files with the configuration settings, perform the analysis, and write the analysis result to a JSON report file. User should make sure the execution credential running tool has access to share folder defined in Configuration.json. When tool runs into access denial issues or the directory does not exist, the tool will exit with proper error message. After the tool copies the log files to the local tool directory, it scans the local data folder and compare with the AG configuration in Configuration.json. If it finds log data is not complete, the tool will show which files are missing. The tool will also alert the user that the failover root cause might not be properly identified due to missing files.

If analysis is successful, the utility persists the analysis result report as JSON file in Result directory. Analysis result will NOT be presented on the console, unless the "--Show" parameter is specified.

<strong>--Analyze - </strong>When "--Analyze" is specified as a parameter, the utility will load configuration file without copying log data. It assumes the log files have already been copied over. It does everything as default mode except copying log data. This option is useful if you already have the data in the local tool execution subdirectories and want to rerun the analysis.<strong>
</strong>

-<strong>-Show</strong> -The utility after analyzing log data will display the results in the command console. Additionally, the results will be persisted to a JSON file in the results folder.<strong>
</strong>

<span style="text-decoration: underline"><strong>Currently supported failover root causes
</strong></span>

The tool in current form can analyze and report failover reason if a failover is due to the following causes.

<strong>Planned Failovers
</strong>
<ul>
 	<li>Stopping SQL service: Admin or other process gracefully shuts down SQL Server hosting the AG primary. In this case, if automatic failover is enabled, Windows notifies WSFC to initiate a failover and picks one secondary as new primary.</li>
 	<li>Shutting down Windows Server: The Windows Server which hosts the SQL Server that has the primary replica is shut down or restarted. In this case, if automatic failover is enabled, Windows notifies WSFC to initiate a failover and picks one secondary as new primary.</li>
 	<li>Manual failover: An administrator performs a manual failover through Management Studio or through a direct Transact-SQL statement "ALTER AVAILABILITY GROUP &lt;AG name&gt; FAILOVER" or "ALTER AVAILABILITY GROUP &lt;AG name&gt; FAILOVER WITH DATA_LOSS" on the secondary replica that will become the primary replica.</li>
</ul>
<strong>SQL Service Internal Health Issue
</strong>
<ul>
 	<li>Too many memory dumps generated on the SQL Server hosting the primary replica: There are more than 100 SQL Server dumps on the primary replica since the last SQL Server restart, and there is at least one dump in the last 10 seconds. In this case, sp_server_diagnostics running in SQL Server determines that SQL Server system component is in error state and notifies failover WSFC to initiate a failover.</li>
 	<li>Memory scribbler: SQL Server has a write access violation and the write address is more than 64KB. If there are more than three such memory corruptions since SQL Server was started, sp_server_diagnostics running in SQL Server determines that SQL Server system component is in error state and notifies failover WSFC to initiate a failover.</li>
 	<li>Sick Spinlock: After an access violation, a spinlock is marked as sick if it backs off more than three times, which is the threshold. In this case, sp_server_diagnostics running in SQL Server determines that SQL Server system component is in error state and notifies failover WSFC to initiate a failover.</li>
 	<li>Out of Memory: If no memory has been freed in 2 minutes, sp_server_diagnostics running in SQL Server determines that SQL Server system component is in error state and notifies failover WSFC to initiate a failover.</li>
 	<li>Unresolved deadlock: If sp_server_diagnostics detects unresolved deadlock from query processing component, it determines that SQL Server system component is in error state and notifies failover WSFC to initiate a failover.</li>
 	<li>Deadlocked scheduler: If sp_server_diagnostics detects deadlocked schedulers from query processing component, it determines that SQL Server system component is in error state and notifies failover WSFC to initiate a failover.</li>
</ul>
<strong>System Wide Issues
</strong>
<ul>
 	<li>Unexpected crash: SQL Server service was shut down unexpectedly. Resources host service (rhs.exe) does not detect lease check from SQL Server about availability group lease. This results an AG lease timeout signal to WSFC and WSFC will initiate a failover.</li>
 	<li>Long dump: SQL Server is creating a dump file. During the process, threads handling the AG lease are frozen and which may result in a lease timeout. This results an AG lease timeout signal to WSFC and WSFC will initiate a failover if automatic failover is enabled.</li>
 	<li>Quorum loss: AG resource is brought offline because quorum is lost. This could be because of a plethora of issues, which would need to be determined by a closure examination of the cluster logs.</li>
 	<li>Network interface failure: Network interface used to communicate between cluster nodes fails. Primary and secondary replicas cannot communicate. WSFC will initiate quorum vote and determine a new primary to fail over to.</li>
 	<li>Cluster disk failure: Network interface used to communicate between cluster nodes has failed, resulting in a communication loss between the cluster nodes. Cluster will initiate quorum vote and determine a new primary failover to.</li>
 	<li>Cluster Service paused: Cluster service on primary was paused, resulting in primary unable to communicate with other nodes in the cluster. Cluster will initiate quorum vote and determine a new primary to fail over to.</li>
 	<li>Node offline: When primary node is frozen or loses power, WSFC loses connection from and to the primary. Failover cluster decide to initiate failover and pick a primary from other possible nodes.</li>
 	<li>High CPU utilization: System wide performance issue causes SQL Server service to be unable to respond to AG lease handler. For example, it is possible that some process on the node is consuming 100% CPU and hence the lease renewal threads cannot execute. This is a best effort estimation based on the inputs from the Cluster logs.</li>
 	<li>High I/O: System wide performance issue causes SQL Server service to be unable to respond to AG lease handler. For example, it is possible that some process on the node is throttling the disks on the system and as such the lease renewal cannot be completed. This is again a best effort estimate based on the inputs from the cluster logs.</li>
</ul>
The Failover Detection utility can be used to analyze SQL Server 2012, 2014, 2016 and 2017 Availability groups, provided the servers are on the latest service packs and cumulative updates.

<span style="text-decoration: underline"><strong>Update 11/21</strong></span>

A few users have reported the following error while using the utility. We are looking into this and will post an update shortly.

“An unhandled exception of type ‘System.BadImageFormatException’ occurred in FailoverDetector.exe
Could not load file or assembly ‘Microsoft.SqlServer.XEvent.Linq, Version=14.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91’ or one of its dependencies. An attempt was made to load a program with an incorrect format.”

<span style="text-decoration: underline"><strong>Update 11/27</strong></span>

New updated binaries for the Failover Detector Utility have been uploaded to GitHub. Before running the utility, please install the "Microsoft Visual C++ Redistributable for Visual Studio 2017" from <a href="https://visualstudio.microsoft.com/downloads/">here</a>. On the download page, scroll down to the "Other Tools and Frameworks" section to download the redistributable (x64 version).

You may encounter the "Strong name validation failed" error while using the utility. To resolve the error use <strong>sn.exe</strong> (available in the zip file) to disable strong name validation. To disable strong name use the following command

<em>sn.exe -Vr &lt;&lt;path to the DLLs&gt;&gt;</em>

&nbsp;

<span style="color: #333333;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe UI', Tahoma, Arial, 'Helvetica Neue', Helvetica, sans-serif;font-size: 14px;font-style: normal;font-weight: 400;float: none;background-color: #ffffff">Sourabh Agarwal</span><br style="color: #333333;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe UI', Tahoma, Arial, 'Helvetica Neue', Helvetica, sans-serif;font-size: 14px;font-style: normal;font-weight: 400;background-color: #ffffff" /><span style="color: #333333;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe UI', Tahoma, Arial, 'Helvetica Neue', Helvetica, sans-serif;font-size: 14px;font-style: normal;font-weight: 400;float: none;background-color: #ffffff">Senior PM, SQL Server Tiger Team</span><br style="color: #333333;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe UI', Tahoma, Arial, 'Helvetica Neue', Helvetica, sans-serif;font-size: 14px;font-style: normal;font-weight: 400;background-color: #ffffff" /><a href="https://twitter.com/SQLSourabh">Twitter<span> </span></a><span style="color: #333333;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe UI', Tahoma, Arial, 'Helvetica Neue', Helvetica, sans-serif;font-size: 14px;font-style: normal;font-weight: 400;float: none;background-color: #ffffff">|<span> </span></span><a href="https://www.linkedin.com/in/napsterreturns/">LinkedIn</a><br style="color: #333333;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe UI', Tahoma, Arial, 'Helvetica Neue', Helvetica, sans-serif;font-size: 14px;font-style: normal;font-weight: 400;background-color: #ffffff" /><span style="color: #333333;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe UI', Tahoma, Arial, 'Helvetica Neue', Helvetica, sans-serif;font-size: 14px;font-style: normal;font-weight: 400;float: none;background-color: #ffffff">Follow us on Twitter:<span> </span></span><a href="https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2ftwitter.com%2fmssqltiger&amp;data=01%7c01%7camit.banerjee%40microsoft.com%7c547e7df7513448a8226908d3a6b9fcab%7c72f988bf86f141af91ab2d7cd011db47%7c1&amp;sdata=R9901KBBJUefMA0ih0XatUJ7lyyTCq4KPOCuyVRSfhI%3d"><span>@mssqltiger</span></a><span style="color: #333333;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe UI', Tahoma, Arial, 'Helvetica Neue', Helvetica, sans-serif;font-size: 14px;font-style: normal;font-weight: 400;float: none;background-color: #ffffff"><span> </span>| Team Blog:<span> </span></span><a href="https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2faka.ms%2fsqlserverteam&amp;data=01%7c01%7camit.banerjee%40microsoft.com%7c547e7df7513448a8226908d3a6b9fcab%7c72f988bf86f141af91ab2d7cd011db47%7c1&amp;sdata=gvN1P32cTULsy3V1nGutsMi7wVrOg9K2VO9GbKCwxAA%3d"><span>Aka.ms/sqlserverteam</span></a>]]></content:encoded>
    </item>
    <item>
      <title>String or Binary data would be truncated: replacing the infamous error 8152</title>
      <link>https://docs.microsoft.com/archive/blogs/sql_server_team/string-or-binary-data-would-be-truncated-replacing-the-infamous-error-8152</link>
      <pubDate>Wed, 24 Oct 2018 12:30:00 GMT</pubDate>
      <dc:creator><![CDATA[Pam Lahoud]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sql_server_team/?p=7695</guid>
      <description><![CDATA[In the recent announcement at Ignite 2018 on the release of SQL Server 2019 CTP 2.0, the new Big...]]></description>
      <content:encoded><![CDATA[In the recent announcement at Ignite 2018 on the release of SQL Server 2019 CTP 2.0, the new <a href="https://cloudblogs.microsoft.com/sqlserver/2018/09/25/introducing-microsoft-sql-server-2019-big-data-clusters/">Big Data Clusters</a>, data virtualization, support for <a target="_blank" href="https://docs.microsoft.com/en-us/sql/relational-databases/collations/collation-and-unicode-support#Unicode_Defn" rel="noopener">UTF-8</a>, and <a href="https://docs.microsoft.com/sql/relational-databases/performance/intelligent-query-processing">Intelligent Query Processing</a> were highlights. But we have also previewed work being done to address the infamous error message “String or binary data would be truncated”.

This error condition may happen for example when you implement an ETL between a source and a destination that does not have matching data types and/or length. In this context, the message "String or binary data would be truncated" is one of the most time-consuming troubleshooting processes to engage in, especially in large datasets. You probably know about and voted for <a target="_blank" href="https://feedback.azure.com/forums/908035-sql-server/suggestions/32908417-binary-or-string-data-would-be-truncated-error" rel="noopener">this</a> feedback item before.

Let’s see an example of what happens when you insert data into a column whose size is not big enough to store it:
<pre class="csharpcode"><span class="kwrd">USE</span> [AdventureWorks2016CTP3]
<span class="kwrd">GO</span>
<span class="kwrd">DROP</span> <span class="kwrd">TABLE</span> <span class="kwrd">IF</span> <span class="kwrd">EXISTS</span> [Sales].[SalesOrderHeaderTest]
<span class="kwrd">GO</span>
<span class="kwrd">CREATE</span> <span class="kwrd">TABLE</span> [Sales].[SalesOrderHeaderTest](
    [SalesOrderID] [<span class="kwrd">INT</span>] <span class="kwrd">NOT</span> <span class="kwrd">NULL</span>,
    [CustomerID] [<span class="kwrd">INT</span>] <span class="kwrd">NOT</span> <span class="kwrd">NULL</span>,
    [CreditCardApprovalCode] [nvarchar](13) <span class="kwrd">NULL</span>
)
<span class="kwrd">GO</span>

INSERT <span class="kwrd">INTO</span> [Sales].[SalesOrderHeaderTest]
<span class="kwrd">SELECT</span> [SalesOrderID], [CustomerID], [CreditCardApprovalCode]
<span class="kwrd">FROM</span> [Sales].[SalesOrderHeader]
GO</pre>
You receive following error message, which admittedly is not very helpful:
<pre class="csharpcode">Msg 8152, <span class="kwrd">Level</span> 16, <span class="kwrd">State</span> 30, Line 13
String <span class="kwrd">or</span> <span class="kwrd">binary</span> <span class="kwrd">data</span> would be truncated.
The <span class="kwrd">statement</span> has been terminated.</pre>
We heard that. Which is why SQL Server 2019 introduces a <strong>new message</strong>, with additional context information. For the same operation, the new error message outputs the following:
<pre class="csharpcode">Msg 2628, <span class="kwrd">Level</span> 16, <span class="kwrd">State</span> 1, Line 14
String <span class="kwrd">or</span> <span class="kwrd">binary</span> <span class="kwrd">data</span> would be truncated <span class="kwrd">in</span> <span class="kwrd">table</span> <span class="str">'AdventureWorks2016CTP3.Sales.SalesOrderHeaderTest'</span>, <span class="kwrd">column</span> <span class="str">'CreditCardApprovalCode'</span>. Truncated <span class="kwrd">value</span>: <span class="str">'1231736Vi8604'</span>.
The <span class="kwrd">statement</span> has been terminated.</pre>
Ok, the new error message provides more context, and now I have the resulting truncated value (not the source value). This is simplifying the troubleshooting process, because now I know the truncated value starts with ‘1231736Vi8604' – that’s 13 characters. And so I can go back to my data source, and locate the source record and its length:
<pre class="csharpcode"><span class="kwrd">SELECT</span> [SalesOrderID], [CustomerID], [CreditCardApprovalCode], LEN([CreditCardApprovalCode])
<span class="kwrd">FROM</span> [Sales].[SalesOrderHeader]
<span class="kwrd">WHERE</span> CreditCardApprovalCode <span class="kwrd">LIKE</span> <span class="str">'1231736Vi8604%'</span></pre>
<a href="https://msdnshared.blob.core.windows.net/media/2018/10/image43.png"><img width="518" height="62" 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/2018/10/image_thumb35.png" border="0" /></a>

It’s 14 characters, and in my table definition I have a NVARCHAR(13). Well, I know what I need to do: change my table data type length.

This new message is also backported to <strong><a target="_blank" href="https://support.microsoft.com/help/4464082" rel="noopener">SQL Server 2017 CU12</a></strong> (and in an upcoming SQL Server 2016 SP2 CU), but not by default. You need to enable <strong>trace flag 460</strong> to replace message ID 8152 with 2628, either at the session or server level.

Note that for now, even in SQL Server 2019 CTP 2.0 the same trace flag 460 needs to be enabled. In a future SQL Server 2019 release, message 2628 will replace message 8152 by default.

Is there a limit to how much of my truncated string this error can return?
Let’s run a small test inserting a 123 character string into a VARCHAR(120):
<pre class="csharpcode"><span class="kwrd">CREATE</span> <span class="kwrd">TABLE</span> myTable (myString <span class="kwrd">VARCHAR</span>(120));
<span class="kwrd">GO</span>
INSERT <span class="kwrd">INTO</span> myTable
<span class="kwrd">VALUES</span> (<span class="str">'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'</span>)
GO</pre>
Although my string gets truncated at 120 characters, the offending value that is shown is truncated to the first 100 characters:
<pre class="csharpcode">Msg 2628, <span class="kwrd">Level</span> 16, <span class="kwrd">State</span> 1, Line 30
String <span class="kwrd">or</span> <span class="kwrd">binary</span> <span class="kwrd">data</span> would be truncated <span class="kwrd">in</span> <span class="kwrd">table</span> <span class="str">'AdventureWorks2016CTP3.dbo.myTable'</span>, <span class="kwrd">column</span> <span class="str">'myString'</span>. Truncated <span class="kwrd">value</span>: <span class="str">'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore '</span>.</pre>
Still plenty to find offending values in most data sources.

Pedro Lopes (<a href="https://twitter.com/SQLPedro">@SQLPedro</a>) – Senior Program Manager]]></content:encoded>
    </item>
    <item>
      <title>SQL Server 2019 CTP 2.0 New Features – Columnstore support for sp_estimate_data_compression_savings</title>
      <link>https://docs.microsoft.com/archive/blogs/sql_server_team/sql-server-2019-ctp-2-0-new-features-columnstore-support-for-sp_estimate_data_compression_savings</link>
      <pubDate>Mon, 22 Oct 2018 08:00:42 GMT</pubDate>
      <dc:creator><![CDATA[Pam Lahoud]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sql_server_team/?p=7715</guid>
      <description><![CDATA[Next up for new Storage Engine area features in SQL Server 2019 is an update to the...]]></description>
      <content:encoded><![CDATA[Next up for new Storage Engine area features in SQL Server 2019 is an update to the <a href="https://docs.microsoft.com/sql/relational-databases/system-stored-procedures/sp-estimate-data-compression-savings-transact-sql">sp_estimate_data_compression_savings</a> stored procedure to add support for both columnstore and columnstore archive compression. This stored procedure has been around since SQL Server 2008 and is handy when you are evaluating whether to compress tables and indexes. The procedure takes five parameters: schema_name, object_name, index_id, partition_number and data_compression. Prior to SQL Server 2019, the data_compression parameter could be 'ROW', 'PAGE' or 'NONE' only. In SQL Server 2019 CTP 2.0, we added two new options here: 'COLUMNSTORE' and 'COLUMNSTORE_ARCHIVE'.

With rowstore tables and indexes, the way you apply compression is to rebuild the object using the desired compression state. Here's an example that will rebuild a heap table with row compression:

<span style="color: blue;font-family: Consolas;font-size: 9pt">ALTER<span style="color: #b00000"> </span><span style="color: black"><span style="color: blue">TABLE<span style="color: black"> Production<span style="color: gray">.<span style="color: black">TransactionHistory <span style="color: blue">REBUILD<span style="color: #b00000"> </span><span style="color: black"><span style="color: blue">PARTITION<span style="color: #b00000"> </span><span style="color: black"><span style="color: gray">=<span style="color: #b00000"> </span><span style="color: black"><span style="color: gray">ALL
<span style="color: black"></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="color: blue;font-family: Consolas;font-size: 9pt">WITH <span style="color: gray">(<span style="color: blue">DATA_COMPRESSION<span style="color: #b00000"> </span><span style="color: black"><span style="color: gray">= <span style="color: black"><span style="color: blue">ROW<span style="color: gray">);
<span style="color: black"></span></span></span></span></span></span></span></span></span><span style="color: blue"><span style="font-family: Consolas;font-size: 9pt">GO<span style="color: black"></span></span></span>

Compression ratios are heavily dependent on the type of data that's being stored in the table, so the only good way to estimate compression space savings is to actually compress a sampling of the data and see what the result is. The way sp_estimate_data_compression_savings works for rowstore compression types is to take a sampling of pages from the source object (up to 5,000 pages) and create a sample object in tempdb that mimics the source object. The sample object is then rebuilt using the desired compression state. An estimated compression ratio is calculated by comparing the original sample object size with the compressed sample object size. This ratio is then used to project the estimated size of the entire source object if the desired compression setting is applied. Keep in mind this can also be used to estimate the size of an object if compression is removed by supplying a data_compression parameter value of 'NONE' for a source object that already has compression applied.

For columnstore compression, you don't really "enable" it, you create a new columnstore index that leverages either standard columnstore or columnstore archive compression. Because of this, the logic of sp_estimate_data_compression_savings when using one of the columnstore options is different than when using one of the rowstore options. When you use a data_compression parameter value of 'COLUMNSTORE' or 'COLUMNSTORE_ARCHIVE' for a rowstore source object, we're not comparing the same rowstore object with different compression states, we're comparing the rowstore object to an equivalent columnstore object. The process is roughly the same: sample pages and create a sample object in tempdb that mimics the source object, build an equivalent columnstore index using the same data, compare the size of the source object with the size of the columnstore index to estimate the compression ratio.

So, what do we consider an "equivalent" columnstore object? We had to make some assumptions here to come up with a suitable columnstore reference object based on the source object. The following table illustrates the different reference object types we use to calculate the compression ratio. These apply to both 'COLUMNSTORE' and 'COLUMNSTORE_ARCHIVE' data_compression options:
<div>
<table style="border-collapse: collapse" border="0"><colgroup> <col style="width: 269px" /> <col style="width: 786px" /></colgroup>
<tbody valign="top">
<tr>
<td valign="bottom" style="border: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt"><strong>Source Object</strong></span></td>
<td valign="bottom" style="border-top: solid #e3e3e3 0.25pt;border-left: none;border-bottom: solid #e3e3e3 0.25pt;border-right: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt"><strong>Reference Object</strong></span></td>
</tr>
<tr>
<td style="border-top: none;border-left: solid #e3e3e3 0.25pt;border-bottom: solid #e3e3e3 0.25pt;border-right: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt">Heap</span></td>
<td style="border-top: none;border-left: none;border-bottom: solid #e3e3e3 0.25pt;border-right: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt">Clustered columnstore index</span></td>
</tr>
<tr>
<td style="border-top: none;border-left: solid #e3e3e3 0.25pt;border-bottom: solid #e3e3e3 0.25pt;border-right: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt">Clustered index</span></td>
<td style="border-top: none;border-left: none;border-bottom: solid #e3e3e3 0.25pt;border-right: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt">Clustered columnstore index</span></td>
</tr>
<tr>
<td style="border-top: none;border-left: solid #e3e3e3 0.25pt;border-bottom: solid #e3e3e3 0.25pt;border-right: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt">Non-clustered index</span></td>
<td style="border-top: none;border-left: none;border-bottom: solid #e3e3e3 0.25pt;border-right: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt">Non-clustered columnstore index (including the key columns and any included columns of the provided non-clustered index, as well as the partition column of the table, if any)</span></td>
</tr>
<tr>
<td style="border-top: none;border-left: solid #e3e3e3 0.25pt;border-bottom: solid #e3e3e3 0.25pt;border-right: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt">Non-clustered columnstore index</span></td>
<td style="border-top: none;border-left: none;border-bottom: solid #e3e3e3 0.25pt;border-right: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt">Non-clustered columnstore index (including the same columns as the provided non-clustered columnstore index)</span></td>
</tr>
<tr>
<td style="border-top: none;border-left: solid #e3e3e3 0.25pt;border-bottom: solid #e3e3e3 0.25pt;border-right: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt">Clustered columnstore index</span></td>
<td style="border-top: none;border-left: none;border-bottom: solid #e3e3e3 0.25pt;border-right: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt">Clustered columnstore index</span></td>
</tr>
</tbody>
</table>
</div>
&nbsp;

You can also estimate in the other direction from columnstore to rowstore compression states. These apply to all the rowstore options, 'ROW', 'PAGE' and 'NONE':

&nbsp;
<div>
<table style="border-collapse: collapse" border="0"><colgroup> <col style="width: 269px" /> <col style="width: 786px" /></colgroup>
<tbody valign="top">
<tr>
<td valign="bottom" style="border: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt"><strong>Source Object</strong></span></td>
<td valign="bottom" style="border-top: solid #e3e3e3 0.25pt;border-left: none;border-bottom: solid #e3e3e3 0.25pt;border-right: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt"><strong>Reference Object</strong></span></td>
</tr>
<tr>
<td style="border-top: none;border-left: solid #e3e3e3 0.25pt;border-bottom: solid #e3e3e3 0.25pt;border-right: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt">Clustered columnstore index</span></td>
<td style="border-top: none;border-left: none;border-bottom: solid #e3e3e3 0.25pt;border-right: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt">Heap</span></td>
</tr>
<tr>
<td style="border-top: none;border-left: solid #e3e3e3 0.25pt;border-bottom: solid #e3e3e3 0.25pt;border-right: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt">Non-clustered columnstore index</span></td>
<td style="border-top: none;border-left: none;border-bottom: solid #e3e3e3 0.25pt;border-right: solid #e3e3e3 0.25pt;padding: 1px"><span style="color: black;font-family: Segoe UI;font-size: 10pt">Non-clustered index (including the columns contained in the non-clustered columnstore index as key columns, and the partition column of the table, if any, as an included column)</span></td>
</tr>
</tbody>
</table>
</div>
&nbsp;

If you use the 'COLUMNSTORE' or 'COLUMNSTORE_ARCHIVE' options for an existing columnstore source object, the procedure works the same as before, it will create a sample columnstore index and rebuild that index with the desired compression state.

Nothing comes for free of course, and while data compression can save a lot of space and therefore a lot of I/O (both logical and physical), the trade off is generally more CPU to compress and decompress the data. In some cases, it may cause performance issues, particularly for data that is heavily updated. This is doubly so for columnstore. These indexes are designed for mostly read data, and heavy updates against columnstores make the structures much less efficient. Leveraging sp_estimate_data_compression_savings along with careful analysis of your workload patterns can help you make the right index and compression choices for your data and application.]]></content:encoded>
    </item>
    <item>
      <title>SQL Server 2019 CTP 2.0 New Features – Introducing the Page Cracker (AKA sys.dm_db_page_info)!</title>
      <link>https://docs.microsoft.com/archive/blogs/sql_server_team/sql-server-2019-ctp-2-0-new-features-introducing-the-page-cracker-aka-sys-dm_db_page_info</link>
      <pubDate>Tue, 16 Oct 2018 08:00:45 GMT</pubDate>
      <dc:creator><![CDATA[Pam Lahoud]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sql_server_team/?p=7665</guid>
      <description><![CDATA[Microsoft Ignite 2018 is fading away in the rearview mirror, but the excitement over all the new...]]></description>
      <content:encoded><![CDATA[Microsoft Ignite 2018 is fading away in the rearview mirror, but the excitement over all the new features and the vision shared there is just beginning. You're probably seeing lots of buzz around the new <a href="https://cloudblogs.microsoft.com/sqlserver/2018/09/25/introducing-microsoft-sql-server-2019-big-data-clusters/">Big Data Clusters</a>, data virtualization and <a href="https://docs.microsoft.com/sql/relational-databases/performance/intelligent-query-processing">Intelligent Query Processing</a> among others, but I wanted to take some time on the blog to dig a little deeper into a few of the improvements we're working on in the storage engine. The first feature is one which I'm particularly excited about – the new <a href="https://docs.microsoft.com/sql/relational-databases/system-dynamic-management-views/sys-dm-db-page-info-transact-sql">sys.dm_db_page_info</a> dynamic management function!

The primary use case we had in mind when developing this function was troubleshooting page-related waits. Some of the key performance scenarios that require page details to diagnose are <a href="https://blogs.msdn.microsoft.com/sql_server_team/tempdb-files-and-trace-flags-and-updates-oh-my/">tempdb contention</a>, <a href="https://support.microsoft.com/kb/4460004">last page insert contention</a> (also see <a href="https://blogs.msdn.microsoft.com/blogdoezequiel/2013/05/23/pagelatch_ex-waits-and-heavy-inserts/">this blog article</a> for code samples) and page-level <a href="https://support.microsoft.com/kb/224453">blocking</a>. All of these scenarios present as either PAGELATCH or lock wait types in sys.dm_exec_query_stats with a page identifier (db_id:file_id:page_id) in the wait_resource column. In order to gain any insight into the problem, you have to know more details about what that page is. Is it a data page, an index page or something else? If it's a data or index page, which object does it belong to? Prior to SQL Server 2019 CTP 2.0, the only way to gain any of this insight was to use the <em>lightly</em> documented command DBCC PAGE. Unfortunately, if you're using some sort of monitoring tool or script to gather data about waits and blocking, there's no good way to include this DBCC PAGE call in those scripts. Not to mention it requires sysadmin privileges. Enter sys.dm_db_page_info.

The sys.dm_db_page_info function takes 4 parameters: database ID, file ID, page ID and mode ('LIMITED' or 'DETAILED'). It returns a table with a single row that contains the header information from the page, including things like object_id, index_id and partition_id. As a standalone function, this provides a documented and fully supported way to retrieve this information without the need for a DBCC command. The real benefit however is the ability to JOIN this function with other DMVs such as sys.dm_exec_requests or sys.sysprocesses to gather this information automatically when there is any sort of page-related contention. If you're familiar with these views you know that the wait_resource column can contain all sorts of different resources, so it's not in the right format to facilitate a direct join to sys.dm_db_page_info. To support this use case, we had to add another column to these views called page_resource. Whenever the wait_resource column contains a page resource, the page_resource column will be populated with an 8-byte hexadecimal value. The page ID is the first four bytes, followed by 2 bytes for the file ID and then 2 bytes for the database ID.

For example:

0x<span style="background-color: silver">48010000</span><span style="background-color: aqua">0100</span><span style="background-color: yellow">0500</span> translates to page <span style="background-color: yellow">5</span>:<span style="background-color: aqua">1</span>:<span style="background-color: silver">328</span>.

Don't worry, you don't have to write T-SQL to do this translation yourself, we've created a new companion function called <a href="https://docs.microsoft.com/sql/relational-databases/system-functions/sys-fn-pagerescracker-transact-sql">sys.fn_PageResCracker</a> that will do this translation for you. Here's a sample script of how you can use these two new functions to help troubleshoot page-related waits:

<span style="color: blue;font-family: Consolas;font-size: 9pt">SELECT<span style="color: black"> page_info<span style="color: gray">.*
<span style="color: black"></span></span></span></span><span style="color: blue;font-family: Consolas;font-size: 9pt">FROM<span style="color: #b00000"> </span><span style="color: black"><span style="color: lime">sys<span style="color: gray">.<span style="color: lime">dm_exec_requests<span style="color: #b00000"> </span><span style="color: black"><span style="color: blue">AS<span style="color: black"> d
</span></span></span></span></span></span></span></span><span style="color: gray;font-family: Consolas;font-size: 9pt">CROSS<span style="color: #b00000"> </span><span style="color: black"><span style="color: gray">APPLY<span style="color: #b00000"> </span><span style="color: black"><span style="color: lime">sys<span style="color: gray">.<span style="color: black">fn_PageResCracker<span style="color: blue"><span style="color: gray">(<span style="color: black">d<span style="color: gray">.<span style="color: black">page_resource<span style="color: gray">)<span style="color: #b00000"> </span><span style="color: black"><span style="color: blue">AS<span style="color: black"> r
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="color: gray"><span style="font-family: Consolas;font-size: 9pt">CROSS<span style="color: #b00000"> </span><span style="color: black"><span style="color: gray">APPLY<span style="color: #b00000"> </span><span style="color: black"><span style="color: lime">sys<span style="color: gray">.<span style="color: black">dm_db_page_info<span style="color: gray">(<span style="color: black">r<span style="color: gray">.<span style="color: fuchsia">db_id<span style="color: gray">,<span style="color: black"> r<span style="color: gray">.<span style="color: fuchsia">file_id<span style="color: gray">,<span style="color: black"> r<span style="color: gray">.<span style="color: black">page_id<span style="color: gray">,<span style="color: black"> 1<span style="color: gray">)<span style="color: #b00000"> </span><span style="color: black"><span style="color: blue">AS<span style="color: black"> page_info</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
</span>

Now that you know the primary use case, let's discuss some limitations. First, this is not a full replacement for DBCC PAGE. DBCC PAGE gives you the entire contents of the page, including header information as well as all the data and the slot array. It can also interpret all this information for you and return it in a user-friendly manner. There are still use cases for this, but they are primarily for things like deep troubleshooting, data corruption analysis and recovery, or simply to illustrate SQL Server concepts such as how indexes are structured. I fully expect to continue to see DBCC PAGE used for demos and illustration purposes, but hopefully its production use can be limited to only those scenarios that absolutely require it.

Another limitation is that we currently only support joins to sys.dm_exec_requests and sys.sysprocesses. We hope to expand this list in the future and are open to suggestions for where you would like to see the page_resource column added. One additional view we have in mind is <a href="https://docs.microsoft.com/sql/relational-databases/system-dynamic-management-views/sys-dm-os-waiting-tasks-transact-sql">sys.dm_os_waiting_tasks</a>, but since this view stores wait resource information differently than sys.dm_exec_requests, it requires a little more work. Please feel free to comment here or send us feedback at <a href="https://aka.ms/sqlfeedback">https://aka.ms/sqlfeedback</a> to let us know how you'd like to use this function in the future.]]></content:encoded>
    </item>
    <item>
      <title>SQL Server 2019 Preview</title>
      <link>https://docs.microsoft.com/archive/blogs/sql_server_team/sql-server-2019-preview</link>
      <pubDate>Wed, 26 Sep 2018 12:06:48 GMT</pubDate>
      <dc:creator><![CDATA[Pam Lahoud]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sql_server_team/?p=7655</guid>
      <description><![CDATA[Earlier this week, we announced SQL Server 2019 Public Preview at Microsoft Ignite. All the features...]]></description>
      <content:encoded><![CDATA[<p>Earlier this week, we announced SQL Server 2019 Public Preview at Microsoft Ignite. All the features that you see in the “<strong><a href="https://docs.microsoft.com/en-us/sql/sql-server/what-s-new-in-sql-server-ver15?view=sql-server-ver15">What’s New</a>”</strong> page are new capabilities that shipped with the CTP 2.0 release. Some of the key changes that people normally wouldn’t associate with SQL Server was the <a href="https://cloudblogs.microsoft.com/sqlserver/2018/09/25/introducing-microsoft-sql-server-2019-big-data-clusters/">introduction of big data clusters</a> which combines Apache Spark and Hadoop into a single data platform called SQL Server. Now you have the ability to combine the power of Spark with SQL Server over your relational and non-relation data sitting in SQL Server, HDFS and other systems like Oracle, Teradata, CosmosDB, etc. This is an amazing way to celebrate the 25th anniversary of <strong>SQL Server.</strong> Not only do we have new capabilities around performance, availability and security for mission critical environments along with capability to leverage hardware innovations like persistent memory and enclaves. But wait that’s not it! We also added <strong>Hadoop, </strong><strong>ApacheSpark, </strong><strong>Kubernetes</strong> and <strong>Java</strong> as native capabilities to our database engine!!! <strong>Happy Birthday SQL Server!!!</strong></p> <p><a href="https://cloudblogs.microsoft.com/sqlserver/2018/09/24/sql-server-2019-preview-combines-sql-server-and-apache-spark-to-create-a-unified-data-platform/">Release announcement for SQL Server 2019 preview</a>  </p><p><a href="https://cloudblogs.microsoft.com/sqlserver/2018/09/25/introducing-microsoft-sql-server-2019-big-data-clusters/">A detailed introduction to SQL Server big data clusters</a>  </p><p><a href="https://cloudblogs.microsoft.com/sqlserver/2018/09/25/azure-data-studio-for-sql-server/">General Availability of Azure Data Studio</a>  </p><p><a href="https://cloudblogs.microsoft.com/sqlserver/2018/09/25/sql-server-2019-preview-containers-now-available/">SQL Server 2019 preview and Containers</a>  </p><p><a href="https://cloudblogs.microsoft.com/sqlserver/2018/09/26/sql-server-2019-celebrating-25-years-of-sql-server-database-engine-and-the-path-forward/">Detailed blog post on database engine enhancements for SQL Server 2019 preview</a>  </p><p>Please stay tuned to the <a href="https://cloudblogs.microsoft.com/sqlserver/">SQL Server blog</a> to know more about the new capabilities and enhancements that will ship in subsequent CTP releases.  </p><p>Below are the videos from the SQL Server 2019 public preview sessions at Ignite. </p><iframe width="640" height="360" src="https://www.youtube.com/embed/videoseries?list=PLpNFxL19GFh5suxRBqfu_p0z2lLbzOtvi" frameborder="0" allowfullscreen></iframe>]]></content:encoded>
    </item>
  </channel>
</rss>