<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>Azure Database Support Blog articles</title>
    <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/bg-p/AzureDBSupport</link>
    <description>Azure Database Support Blog articles</description>
    <pubDate>Mon, 29 Jun 2026 01:29:14 GMT</pubDate>
    <dc:creator>AzureDBSupport</dc:creator>
    <dc:date>2026-06-29T01:29:14Z</dc:date>
    <item>
      <title>Generic Best Practices for HikariCP with Azure Database for PostgreSQL</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/generic-best-practices-for-hikaricp-with-azure-database-for/ba-p/4531059</link>
      <description>&lt;P&gt;&lt;STRONG&gt;Author:&lt;/STRONG&gt; Mohamed Baioumy&lt;BR /&gt;&lt;STRONG&gt;Technology:&lt;/STRONG&gt; Azure Database for PostgreSQL (Flexible Server &amp;amp; Single Server)&lt;BR /&gt;&lt;STRONG&gt;Category:&lt;/STRONG&gt; Connectivity | Performance | Application Design&lt;/P&gt;
&lt;H2&gt;Introduction&lt;/H2&gt;
&lt;P&gt;Connection pooling is a critical component of application performance when connecting to Azure Database for PostgreSQL. Creating a new PostgreSQL connection is an expensive operation that consumes CPU, memory, and networking resources. Reusing existing connections through a connection pool significantly reduces connection latency, improves throughput, and helps applications scale more efficiently.&lt;/P&gt;
&lt;P&gt;Many Java applications use&amp;nbsp;&lt;STRONG&gt;HikariCP&lt;/STRONG&gt;, one of the most popular high-performance JDBC connection pools. While HikariCP provides excellent performance out of the box, improperly configured connection pool settings can lead to issues such as:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Connection pool exhaustion&lt;/LI&gt;
&lt;LI&gt;Stale or invalid connections&lt;/LI&gt;
&lt;LI&gt;Increased connection acquisition latency&lt;/LI&gt;
&lt;LI&gt;Excessive connection creation and destruction&lt;/LI&gt;
&lt;LI&gt;Database resource contention&lt;/LI&gt;
&lt;LI&gt;Application timeouts&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This article summarizes generic guidance and best practices for configuring HikariCP when working with &lt;STRONG&gt;Azure Database for PostgreSQL Flexible Server&lt;/STRONG&gt; and &lt;STRONG&gt;Azure Database for PostgreSQL Single Server&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H1&gt;Understanding Key HikariCP Parameters&lt;/H1&gt;
&lt;H2&gt;1. Maximum Lifetime (maxLifetime)&lt;/H2&gt;
&lt;P&gt;The maxLifetime property controls how long a connection can remain in the pool before HikariCP retires it and creates a new one.&lt;/P&gt;
&lt;H3&gt;Why It Matters&lt;/H3&gt;
&lt;P&gt;Connections can become stale over time due to:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Network interruptions&lt;/LI&gt;
&lt;LI&gt;Infrastructure updates&lt;/LI&gt;
&lt;LI&gt;Connection state changes&lt;/LI&gt;
&lt;LI&gt;TCP idle behavior&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Recycling connections periodically helps prevent applications from using long-lived connections that may no longer be healthy.&lt;/P&gt;
&lt;H3&gt;Recommended Practice&lt;/H3&gt;
&lt;P&gt;Avoid configuring the value too low.&lt;/P&gt;
&lt;P&gt;When maxLifetime is set aggressively, HikariCP continuously destroys and recreates connections, resulting in:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Additional authentication overhead&lt;/LI&gt;
&lt;LI&gt;Increased connection establishment latency&lt;/LI&gt;
&lt;LI&gt;Higher CPU utilization&lt;/LI&gt;
&lt;LI&gt;Reduced application throughput&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;A reasonable starting point is:&lt;/H3&gt;
&lt;LI-CODE lang=""&gt;spring.datasource.hikari.maxLifetime=1800000&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;30 minutes (1,800,000 ms)&lt;/STRONG&gt; is commonly used and aligns well with many production workloads. Depending on workload characteristics, values between &lt;STRONG&gt;30 minutes and 1 hour&lt;/STRONG&gt; are generally suitable&lt;/P&gt;
&lt;H3&gt;Avoid&lt;/H3&gt;
&lt;LI-CODE lang=""&gt;maxLifetime=300000&lt;/LI-CODE&gt;
&lt;P&gt;(5 minutes)&lt;/P&gt;
&lt;P&gt;This often causes unnecessary connection churn without providing additional benefits.&lt;/P&gt;
&lt;H2&gt;2. Minimum Idle Connections (minimumIdle)&lt;/H2&gt;
&lt;P&gt;The minimumIdle setting defines how many idle connections HikariCP should keep ready for immediate use.&lt;/P&gt;
&lt;H3&gt;Why It Matters&lt;/H3&gt;
&lt;P&gt;A pool with available idle connections can serve application requests immediately without waiting for new connections to be established.&lt;/P&gt;
&lt;P&gt;However, maintaining too many idle connections consumes unnecessary database resources.&lt;/P&gt;
&lt;H3&gt;Recommended Practice&lt;/H3&gt;
&lt;P&gt;For most workloads:&lt;/P&gt;
&lt;LI-CODE lang=""&gt;minimumIdle = maximumPoolSize&lt;/LI-CODE&gt;
&lt;P&gt;Or&lt;/P&gt;
&lt;LI-CODE lang=""&gt;minimumIdle slightly lower than maximumPoolSize&lt;/LI-CODE&gt;
&lt;P&gt;This ensures sufficient connections are already available during traffic spikes while avoiding excessive connection creation delays.&lt;/P&gt;
&lt;H3&gt;Example&lt;/H3&gt;
&lt;LI-CODE lang=""&gt;maximumPoolSize=20
minimumIdle=15
&lt;/LI-CODE&gt;
&lt;H3&gt;Avoid&lt;/H3&gt;
&lt;LI-CODE lang=""&gt;maximumPoolSize=20
minimumIdle=20&lt;/LI-CODE&gt;
&lt;P&gt;only when the application experiences long periods of inactivity and conserving resources is more important than immediate responsiveness.&lt;/P&gt;
&lt;H2&gt;3. Idle Timeout (idleTimeout)&lt;/H2&gt;
&lt;P&gt;The idleTimeout property determines how long an unused connection remains in the pool before being removed.&lt;/P&gt;
&lt;H3&gt;Why It Matters&lt;/H3&gt;
&lt;P&gt;Connections that sit idle for extended periods consume resources on both:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The application server&lt;/LI&gt;
&lt;LI&gt;Azure Database for PostgreSQL&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;However, removing idle connections too quickly causes the application to repeatedly establish new connections.&lt;/P&gt;
&lt;H3&gt;Recommended Practice&lt;/H3&gt;
&lt;P&gt;Keep the default value unless there is a specific requirement.&lt;/P&gt;
&lt;LI-CODE lang=""&gt;spring.datasource.hikari.idleTimeout=600000&lt;/LI-CODE&gt;
&lt;P&gt;which equals:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;10 minutes (600,000 ms)&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;This setting provides a good balance between resource utilization and responsiveness. &lt;A href="https://outlook.office365.com/owa/?ItemID=AAMkADRjODQyNmEzLTIwNzEtNDdlYS05NzA3LTdkMjJiMmRhYWViZgBGAAAAAADXD8kqqM60QIcyt%2fhmrKq3BwA%2f7EuMbet6Qp8LYyRnUrzaAAAAAAEMAAD1cVSUcJQ0TpiatSE1Iv6IAAen4KcQAAA%3d&amp;amp;exvsurl=1&amp;amp;viewmodel=ReadMessageItem" target="_blank"&gt;[Re: EXT: R...0040002947 | Outlook]&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;The timeout should also be comfortably longer than any expected short application idle periods.&lt;/P&gt;
&lt;H3&gt;Avoid&lt;/H3&gt;
&lt;LI-CODE lang=""&gt;idleTimeout=10000&lt;/LI-CODE&gt;
&lt;P&gt;(10 seconds)&lt;/P&gt;
&lt;P&gt;Such aggressive settings often result in unnecessary connection creation cycles.&lt;/P&gt;
&lt;H2&gt;4. Maximum Pool Size (maximumPoolSize)&lt;/H2&gt;
&lt;P&gt;This parameter determines the maximum number of concurrent database connections the application can maintain.&lt;/P&gt;
&lt;H3&gt;Why It Matters&lt;/H3&gt;
&lt;P&gt;This is often the most important HikariCP setting.&lt;/P&gt;
&lt;H3&gt;If the Pool Is Too Small&lt;/H3&gt;
&lt;P&gt;Applications may experience:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Connection is not available, request timed out&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;because all available connections are already in use. Similar scenarios have been observed during customer investigations involving Hikari pool exhaustion.&lt;/P&gt;
&lt;H3&gt;If the Pool Is Too Large&lt;/H3&gt;
&lt;P&gt;Applications can overwhelm the database server with excessive concurrent sessions, resulting in:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Connection contention&lt;/LI&gt;
&lt;LI&gt;Increased context switching&lt;/LI&gt;
&lt;LI&gt;Higher memory consumption&lt;/LI&gt;
&lt;LI&gt;Reduced overall performance&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Recommended Practice&lt;/H3&gt;
&lt;P&gt;Pool size should be based on:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Database compute configuration&lt;/LI&gt;
&lt;LI&gt;CPU core count&lt;/LI&gt;
&lt;LI&gt;Query execution duration&lt;/LI&gt;
&lt;LI&gt;Application concurrency requirements&lt;/LI&gt;
&lt;LI&gt;Workload characteristics&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;There is no universal value that fits every workload.&lt;/P&gt;
&lt;P&gt;Start conservatively:&lt;/P&gt;
&lt;LI-CODE lang=""&gt;maximumPoolSize=10&lt;/LI-CODE&gt;
&lt;P&gt;or&lt;/P&gt;
&lt;P&gt;maximumPoolSize=20&lt;/P&gt;
&lt;LI-CODE lang=""&gt;maximumPoolSize=20&lt;/LI-CODE&gt;
&lt;P&gt;and increase only after load testing demonstrates a need for additional concurrency.&lt;/P&gt;
&lt;H1&gt;Fixed-Size Pool Recommendation&lt;/H1&gt;
&lt;P&gt;For many production workloads, a &lt;STRONG&gt;fixed-size pool&lt;/STRONG&gt; provides the simplest and most predictable behavior.&lt;/P&gt;
&lt;P&gt;Configure:&lt;/P&gt;
&lt;LI-CODE lang=""&gt;maximumPoolSize=20
minimumIdle=20&lt;/LI-CODE&gt;
&lt;P&gt;or omit minimumIdle entirely so it defaults to maximumPoolSize. HikariCP commonly recommends maintaining a fixed-size pool for responsiveness during demand spikes.&lt;/P&gt;
&lt;H3&gt;Benefits&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;Faster connection acquisition&lt;/LI&gt;
&lt;LI&gt;Predictable performance&lt;/LI&gt;
&lt;LI&gt;Reduced connection creation latency&lt;/LI&gt;
&lt;LI&gt;Better handling of traffic spikes&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;When using a small fixed-size pool, there is often little need to aggressively tune:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;minimumIdle&lt;/LI&gt;
&lt;LI&gt;idleTimeout&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Instead, simply recycle connections using:&lt;/P&gt;
&lt;P&gt;maxLifetime&lt;/P&gt;
&lt;LI-CODE lang=""&gt;maxLifetime&lt;/LI-CODE&gt;
&lt;H1&gt;Additional Recommendations&lt;/H1&gt;
&lt;H2&gt;Enable TCP Keepalive&lt;/H2&gt;
&lt;P&gt;One common cause of stale connections is network devices silently dropping inactive TCP sessions.&lt;/P&gt;
&lt;P&gt;For PostgreSQL applications, consider enabling TCP keepalive:&lt;/P&gt;
&lt;P&gt;tcpKeepAlive=true&lt;/P&gt;
&lt;LI-CODE lang=""&gt;tcpKeepAlive=true&lt;/LI-CODE&gt;
&lt;P&gt;The HikariCP project specifically recommends enabling TCP keepalive to prevent rare situations where pools can lose valid connections.&lt;/P&gt;
&lt;H2&gt;Monitor Connection Usage&lt;/H2&gt;
&lt;P&gt;Track:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Active connections&lt;/LI&gt;
&lt;LI&gt;Idle connections&lt;/LI&gt;
&lt;LI&gt;Connection acquisition time&lt;/LI&gt;
&lt;LI&gt;Pool exhaustion events&lt;/LI&gt;
&lt;LI&gt;Database connection counts&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;These metrics help identify whether pool sizing is appropriate.&lt;/P&gt;
&lt;H2&gt;Investigate Long-Running Queries&lt;/H2&gt;
&lt;P&gt;Connection pool problems are often symptoms rather than root causes.&lt;/P&gt;
&lt;P&gt;A frequent scenario is:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;A query becomes slow.&lt;/LI&gt;
&lt;LI&gt;Connections remain occupied longer.&lt;/LI&gt;
&lt;LI&gt;The pool becomes exhausted.&lt;/LI&gt;
&lt;LI&gt;Applications start timing out.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;When analyzing HikariCP issues, always review:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Query performance&lt;/LI&gt;
&lt;LI&gt;Blocking situations&lt;/LI&gt;
&lt;LI&gt;Database resource utilization&lt;/LI&gt;
&lt;LI&gt;Application connection handling logic&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;Sample Production Configuration&lt;/H1&gt;
&lt;P&gt;spring.datasource.hikari.maximumPoolSize=20&lt;/P&gt;
&lt;P&gt;spring.datasource.hikari.minimumIdle=15&lt;/P&gt;
&lt;P&gt;spring.datasource.hikari.maxLifetime=1800000&lt;/P&gt;
&lt;P&gt;spring.datasource.hikari.idleTimeout=600000&lt;/P&gt;
&lt;P&gt;spring.datasource.hikari.connectionTimeout=30000&lt;/P&gt;
&lt;P&gt;spring.datasource.hikari.keepaliveTime=60000&lt;/P&gt;
&lt;LI-CODE lang=""&gt;spring.datasource.hikari.maximumPoolSize=20
spring.datasource.hikari.minimumIdle=15
spring.datasource.hikari.maxLifetime=1800000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.keepaliveTime=60000&lt;/LI-CODE&gt;
&lt;P&gt;This configuration provides a solid starting point for many Azure Database for PostgreSQL workloads and can be adjusted based on application-specific requirements.&lt;/P&gt;
&lt;P&gt;a { text-decoration: none; color: #464feb; } tr th, tr td { border: 1px solid #e6e6e6; } tr th { background-color: #f5f5f5; }&lt;/P&gt;
&lt;H1&gt;Conclusion&lt;/H1&gt;
&lt;P&gt;HikariCP is extremely efficient when configured appropriately. The goal is not to maximize the number of connections, but rather to maintain a healthy balance between application responsiveness and database resource consumption.&lt;/P&gt;
&lt;P&gt;As a general rule:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Use a reasonable maxLifetime (30–60 minutes)&lt;/LI&gt;
&lt;LI&gt;Keep enough idle connections available for traffic spikes&lt;/LI&gt;
&lt;LI&gt;Avoid aggressive idleTimeout values&lt;/LI&gt;
&lt;LI&gt;Size the pool based on workload characteristics, not guesses&lt;/LI&gt;
&lt;LI&gt;Consider fixed-size pools for predictable performance&lt;/LI&gt;
&lt;LI&gt;Monitor connection usage and query performance regularly&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;By following these practices, applications connecting to Azure Database for PostgreSQL can achieve improved scalability, lower latency, and more reliable connectivity.&lt;/P&gt;
&lt;H2&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;References&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/postgresql/connectivity/concepts-connection-pooling-best-practices" target="_blank"&gt;Connection pooling best practices - Azure Database for PostgreSQL&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A class="lia-external-url" href="https://azure.microsoft.com/en-us/blog/performance-best-practices-for-using-azure-database-for-postgresql-connection-pooling/" target="_blank"&gt;Performance best practices for using Azure Database for PostgreSQL – Connection Pooling&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A class="lia-external-url" href="https://github.com/brettwooldridge/HikariCP" target="_blank"&gt;HikariCP Documentation and Pool Sizing Guidance&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 26 Jun 2026 22:05:48 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/generic-best-practices-for-hikaricp-with-azure-database-for/ba-p/4531059</guid>
      <dc:creator>Mohamed_Baioumy_MSFT</dc:creator>
      <dc:date>2026-06-26T22:05:48Z</dc:date>
    </item>
    <item>
      <title>Lessons Learned #541:Automatic Plan Correction vs External Tables: A Practical Lesson from the Field</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/lessons-learned-541-automatic-plan-correction-vs-external-tables/ba-p/4531400</link>
      <description>&lt;P&gt;&lt;STRONG&gt;Automatic Plan Correction&lt;/STRONG&gt; is one of the most useful capabilities in Azure SQL Database when dealing with &lt;STRONG&gt;plan regressions&lt;/STRONG&gt;. It uses Query Store to identify when a query starts using a worse execution plan and, when appropriate, &lt;STRONG&gt;forces the last known good plan&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;However, during a recent troubleshooting scenario, I found that not all queries have the same execution characteristics. In particular, &lt;STRONG&gt;queries that reference external tables&lt;/STRONG&gt; may behave differently from fully local queries because part of their execution depends on remote data access.&lt;/P&gt;
&lt;P&gt;When Query Store is configured to capture all queries, we can use it to identify queries that reference external tables and review whether those query IDs should participate in FORCE_LAST_GOOD_PLAN.&lt;/P&gt;
&lt;P&gt;From a practical perspective, external-table queries may not always be the best candidates for Automatic Plan Correction, especially when the expected benefit of automatic plan forcing is not clear. For that reason, the goal of this article is simple: identify queries that reference external tables and, when appropriate, exclude selected query IDs from Automatic Plan Correction.&lt;/P&gt;
&lt;P&gt;If we review the execution plan for the following query:&amp;nbsp;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;DECLARE @Region nvarchar(50) = N'EMEA' 
SELECT CustomerId, CustomerName, Region 
FROM dbo.ExternalCustomers 
WHERE Region = @Region;&lt;/LI-CODE&gt;
&lt;P&gt;We can see that the plan includes a&amp;nbsp;&lt;STRONG&gt;Remote Query operator&lt;/STRONG&gt;. This means that the query is not only accessing local data; part of the execution depends on remote data access through the external table.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;For this type of query, &lt;STRONG&gt;Automatic Plan Correction&lt;/STRONG&gt; may not provide the same clear benefit as it does for fully local queries. The performance may depend not only on the local execution plan, but also on the remote database, the external data source, network latency, and the amount of data returned from the remote side.&lt;/P&gt;
&lt;P&gt;For that reason, queries referencing external tables are good candidates for review before allowing them to participate in &lt;STRONG&gt;FORCE_LAST_GOOD_PLAN.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In this scenario, the first step was to identify the Query Store query_id associated with the query referencing the external table. Since the query text was available in Query Store, we searched for the external table name in sys.query_store_query_text.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT
    q.query_id,
    p.plan_id,
    p.is_forced_plan,
    p.plan_forcing_type_desc,
    p.force_failure_count,
    p.last_force_failure_reason_desc,
    p.last_execution_time,
    qt.query_sql_text
FROM sys.query_store_query_text AS qt
INNER JOIN sys.query_store_query AS q
    ON qt.query_text_id = q.query_text_id
INNER JOIN sys.query_store_plan AS p
    ON q.query_id = p.query_id
WHERE qt.query_sql_text LIKE N'%ExternalCustomers%'
ORDER BY
    p.last_execution_time DESC;
&lt;/LI-CODE&gt;
&lt;P&gt;Once the query_id was identified, the next step was to exclude that specific query from Automatic Plan Correction by setting FORCE_LAST_GOOD_PLAN to OFF for that query_id.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;EXECUTE sys.sp_configure_automatic_tuning @option = 'FORCE_LAST_GOOD_PLAN', @type = 'QUERY', @type_value = N'&amp;lt;query_id&amp;gt;', @option_value = 'OFF';&lt;/LI-CODE&gt;
&lt;P&gt;For example:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;EXECUTE sys.sp_configure_automatic_tuning @option = 'FORCE_LAST_GOOD_PLAN', @type = 'QUERY', @type_value = N'1574', @option_value = 'OFF';&lt;/LI-CODE&gt;
&lt;P&gt;This does not disable Automatic Plan Correction for the entire database. It only tells Automatic Plan Correction to ignore this specific Query Store query ID for FORCE_LAST_GOOD_PLAN.&lt;/P&gt;
&lt;P&gt;With this approach, Automatic Plan Correction can remain enabled for the rest of the database workload, while selected queries that depend on external or remote data access can be reviewed and excluded individually when automatic plan forcing is not expected to provide a clear benefit.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 26 Jun 2026 20:49:11 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/lessons-learned-541-automatic-plan-correction-vs-external-tables/ba-p/4531400</guid>
      <dc:creator>Jose_Manuel_Jurado</dc:creator>
      <dc:date>2026-06-26T20:49:11Z</dc:date>
    </item>
    <item>
      <title>Data sync fails with deadlock error</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/data-sync-fails-with-deadlock-error/ba-p/4526202</link>
      <description>&lt;P&gt;Recently I have worked on cases where it is observed that data sync fails with deadlock error.&lt;/P&gt;
&lt;P&gt;Error:&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Database re-provisioning failed with the exception 'Transaction (Process ID ##) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;To investigate deadlocks, you can enable Extended Events by following the guidance provided here:&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/database/analyze-prevent-deadlocks?view=azuresql&amp;amp;tabs=event-file#collect-deadlock-graphs-in-azure-sql-database-with-extended-events" target="_blank" rel="noopener"&gt;https://learn.microsoft.com/en-us/azure/azure-sql/database/analyze-prevent-deadlocks?view=azuresql&amp;amp;tabs=event-file#collect-deadlock-graphs-in-azure-sql-database-with-extended-events&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;A Sample deadlock graph looks below:&lt;/U&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;img /&gt;&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Running the Data Sync Health Checker report also results in the same error being observed.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://github.com/microsoft/AzureSQLDataSyncHealthChecker" target="_blank" rel="noopener"&gt;https://github.com/microsoft/AzureSQLDataSyncHealthChecker&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Database re-provisioning failed with the exception 'Transaction (Process ID ##) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Explanation:&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;When a deadlock occurs between a Data Sync operation and a customer transaction, the Data Sync operation is always selected as the victim.&lt;/P&gt;
&lt;P&gt;To mitigate this issue without removing and recreating the Data Sync configuration, please follow the below steps:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Remove the table referenced in the deadlock error from the Data Sync configuration and then restart the synchronization.&lt;/LI&gt;
&lt;LI&gt;If automatic synchronization is enabled, disable the schedule and run the sync process manually.&lt;/LI&gt;
&lt;LI&gt;Increase the frequency of the synchronization process to minimize overlapping operations and reduce the likelihood of deadlocks.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Additionally, running UPDATE STATISTICS and rebuilding indexes on the system tables involved in Data Sync may help improve performance. This can assist the SQL optimizer in selecting a more efficient execution plan, thereby allowing the synchronization process to complete faster and reducing the likelihood of deadlocks.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;Please note that Azure SQL Data Sync will be retired on September 30, 2027.&lt;/STRONG&gt;&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;For more details, refer to the official documentation:&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/database/sql-data-sync-data-sql-server-sql-database?view=azuresql" target="_blank" rel="noopener"&gt;https://learn.microsoft.com/en-us/azure/azure-sql/database/sql-data-sync-data-sql-server-sql-database?view=azuresql&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 22 Jun 2026 09:06:18 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/data-sync-fails-with-deadlock-error/ba-p/4526202</guid>
      <dc:creator>SmritiGupta</dc:creator>
      <dc:date>2026-06-22T09:06:18Z</dc:date>
    </item>
    <item>
      <title>Azure SQL DB Fabric Mirroring with Private Endpoint</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/azure-sql-db-fabric-mirroring-with-private-endpoint/ba-p/4529793</link>
      <description>&lt;P&gt;&lt;STRONG&gt;Introduction&lt;BR /&gt;&lt;/STRONG&gt;Overview steps for configuration of Mirroring between Azure SQL Database to Fabric Mirrored Database over Private Endpoint and Public Connectivity Disabled on source.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;BR /&gt;Prerequisites&lt;BR /&gt;#1&lt;/STRONG&gt; - The minimum requirement for the source Azure SQL Database tier is - it is Standard Tier with DTUs equal or greater than 100.&lt;BR /&gt;Free, Basic Tier, or &amp;lt;100 DTUs are NOT supported.&lt;BR /&gt;All vCore model tiers supported.&lt;BR /&gt;&lt;BR /&gt;&lt;STRONG&gt;#2&lt;/STRONG&gt; - System Assigned Managed Identity (SAMI) must be enabled on the Azure SQL logical server.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;#3&lt;/STRONG&gt;&amp;nbsp;- Microsoft.PowerPlatform should be registered as a source provider at the subscription level.&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;If this step is not completed, you'll face error in the next steps, while creating the 'Virtual Network Data Gateway', example below.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;#4 &lt;/STRONG&gt;- The Virtual Network Subnet of the configured Private Endpoint should have the following selected.&lt;BR /&gt;Select Microsoft.PowerPlatform/netaccesslinks for the Subnet Delegation tab.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;This is a required step, otherwise the subnet is grayed out to select while configuration of the Virtual Network Data Gateway at Fabric level.&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;&lt;STRONG&gt;High Level Configuration Steps&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;#1&amp;nbsp;&lt;/STRONG&gt;- Go to Fabric Portal &amp;gt; Your Workspace&lt;BR /&gt;Click on Settings button on top right &amp;gt; Click on Manage Connections and Gateways&lt;BR /&gt;Go to 'Virtual Network Data Gateway' tab &amp;gt; Click New&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;In the new page, Select your Capacity, Subscription, Resource Group, VNET and Subnet of the source Azure SQL DB and create it.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;#2&lt;/STRONG&gt;&amp;nbsp;- Go back to your workspace, and click new item &amp;gt; Search 'Mirrored Azure SQL Database'&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;#3&lt;/STRONG&gt;&amp;nbsp;- Here, in Data Gateway section, chose your new created gateway which we created in previous step, and fill the required source Azure SQL Database details and click connect.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;#4&lt;/STRONG&gt; - Select the tables to be mirrored in the next steps and you will be able to successfully mirror from Azure SQL Database to Mirrored Azure SQL Database without Public Connectivity and using Private Endpoint.&lt;/P&gt;</description>
      <pubDate>Mon, 22 Jun 2026 10:49:15 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/azure-sql-db-fabric-mirroring-with-private-endpoint/ba-p/4529793</guid>
      <dc:creator>shaurya-singh</dc:creator>
      <dc:date>2026-06-22T10:49:15Z</dc:date>
    </item>
    <item>
      <title>Troubleshooting Azure SQL Data Sync Failures Caused by Large Change Tracking Backlogs</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/troubleshooting-azure-sql-data-sync-failures-caused-by-large/ba-p/4529337</link>
      <description>&lt;H2&gt;Introduction&lt;/H2&gt;
&lt;P&gt;Azure SQL Data Sync is a popular solution for synchronizing data across multiple Azure SQL Database instances. It uses Change Tracking to identify and propagate data modifications between participating databases. While Data Sync can operate reliably for extended periods, environments with highly active tables may occasionally encounter synchronization failures that become increasingly difficult to recover from.&lt;/P&gt;
&lt;P&gt;In this article, we examine a real-world troubleshooting scenario in which Azure SQL Data Sync repeatedly failed while attempting to synchronize changes for a specific table. The investigation revealed that excessive synchronization metadata growth and a large change backlog were causing change enumeration operations to exceed Azure SQL Database resource governance thresholds, resulting in repeated synchronization failures.&lt;/P&gt;
&lt;P&gt;This post explains the symptoms, investigation process, troubleshooting scripts, root cause, mitigation strategy, and preventive measures that administrators can apply in their own Azure SQL Data Sync environments.&lt;/P&gt;
&lt;H1&gt;Symptoms&lt;/H1&gt;
&lt;P&gt;The issue manifested as repeated Azure SQL Data Sync failures for a single synchronized table while the sync group remained unhealthy.&lt;/P&gt;
&lt;P&gt;Administrators may encounter errors similar to:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Cannot enumerate changes at the RelationalSyncProvider.&lt;/P&gt;
&lt;P&gt;SqlError Number: 40197&lt;/P&gt;
&lt;P&gt;The service has encountered an error processing your request.&lt;/P&gt;
&lt;P&gt;Please try again.&lt;/P&gt;
&lt;P&gt;Error code 40549&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;These errors can occur when Data Sync attempts to enumerate pending changes through Change Tracking and synchronization metadata, but the operation becomes excessively resource intensive.&lt;/P&gt;
&lt;H3&gt;Additional Warning Signs&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;Synchronization runs taking significantly longer than usual&lt;/LI&gt;
&lt;LI&gt;Repeated synchronization retries&lt;/LI&gt;
&lt;LI&gt;Increasing synchronization latency&lt;/LI&gt;
&lt;LI&gt;Large Data Sync metadata growth&lt;/LI&gt;
&lt;LI&gt;Sync groups reporting warning or failed states&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;Understanding How Azure SQL Data Sync Uses Change Tracking&lt;/H1&gt;
&lt;P&gt;Azure SQL Data Sync relies on SQL Change Tracking to identify modifications occurring within synchronized tables.&lt;/P&gt;
&lt;P&gt;The synchronization architecture generally consists of:&lt;/P&gt;
&lt;H3&gt;Hub Database&lt;/H3&gt;
&lt;P&gt;The central synchronization endpoint responsible for orchestrating synchronization.&lt;/P&gt;
&lt;H3&gt;Member Databases&lt;/H3&gt;
&lt;P&gt;Databases that participate in synchronization and exchange data with the hub.&lt;/P&gt;
&lt;H3&gt;Change Tracking&lt;/H3&gt;
&lt;P&gt;Tracks data modifications and provides an efficient mechanism to identify rows that have changed since the last synchronization cycle.&lt;/P&gt;
&lt;H3&gt;Synchronization Metadata&lt;/H3&gt;
&lt;P&gt;Data Sync maintains internal metadata used to track synchronization state and determine which changes must be applied.&lt;/P&gt;
&lt;H3&gt;Change Enumeration&lt;/H3&gt;
&lt;P&gt;During synchronization, Azure SQL Data Sync enumerates tracked changes and applies them across participating databases.&lt;/P&gt;
&lt;P&gt;As synchronization backlog grows, the complexity and duration of enumeration operations increase accordingly.&lt;/P&gt;
&lt;H1&gt;Investigation Process&lt;/H1&gt;
&lt;P&gt;The troubleshooting effort focused on identifying where synchronization was failing and determining whether the underlying issue was related to Change Tracking, synchronization metadata, or Azure SQL resource limitations.&lt;/P&gt;
&lt;H3&gt;Step 1 – Identify the Failing Object&lt;/H3&gt;
&lt;P&gt;Review synchronization logs to determine which table repeatedly generates failures.&lt;/P&gt;
&lt;H3&gt;Step 2 – Determine Where the Failure Occurs&lt;/H3&gt;
&lt;P&gt;Determine whether the issue originates from:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Hub Database&lt;/LI&gt;
&lt;LI&gt;Member Database&lt;/LI&gt;
&lt;LI&gt;Synchronization Infrastructure&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Step 3 – Evaluate Synchronization Backlog&lt;/H3&gt;
&lt;P&gt;Assess the volume of pending changes and synchronization metadata growth.&lt;/P&gt;
&lt;H3&gt;Step 4 – Assess Resource Governance Impact&lt;/H3&gt;
&lt;P&gt;Evaluate whether Azure SQL Database resource governance may be terminating synchronization-related operations.&lt;/P&gt;
&lt;H1&gt;Useful T-SQL Scripts for Azure SQL Data Sync Troubleshooting&lt;/H1&gt;
&lt;P&gt;During the investigation, several T-SQL queries were used to validate Change Tracking configuration, evaluate synchronization backlog size, identify governance-related interruptions, and assess the overall health of the Azure SQL environment.&lt;/P&gt;
&lt;P&gt;All scripts below have been sanitized and generalized for public use.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;Note:&lt;/STRONG&gt; Replace dbo.SyncTable with the affected synchronized table in your environment.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H2&gt;1. Verify Whether Change Tracking Is Enabled&lt;/H2&gt;
&lt;P&gt;Azure SQL Data Sync requires Change Tracking to function correctly.&lt;/P&gt;
&lt;H3&gt;Check Database-Level Change Tracking&lt;/H3&gt;
&lt;LI-CODE lang="sql"&gt;-- Run to Master DB
SELECT
    DB_NAME(database_id) AS DatabaseName,
    is_auto_cleanup_on,
    retention_period,
    retention_period_units_desc
FROM sys.change_tracking_databases
WHERE database_id = DB_ID();&lt;/LI-CODE&gt;
&lt;H3&gt;Check Table-Level Change Tracking&lt;/H3&gt;
&lt;LI-CODE lang="sql"&gt;-- Run to UserDB
SELECT
    OBJECT_SCHEMA_NAME(object_id) AS SchemaName,
    OBJECT_NAME(object_id) AS TableName,
    begin_version,
    cleanup_version,
    min_valid_version
FROM sys.change_tracking_tables
WHERE object_id = OBJECT_ID('dbo.SyncTable');&lt;/LI-CODE&gt;
&lt;H3&gt;Why This Matters&lt;/H3&gt;
&lt;P&gt;If Change Tracking is disabled, Azure SQL Data Sync cannot enumerate changes successfully.&lt;/P&gt;
&lt;H2&gt;2. Estimate Synchronization Backlog Size&lt;/H2&gt;
&lt;P&gt;One of the most useful troubleshooting indicators is the volume of pending changes.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;--Run to UserDb
SELECT COUNT(*) AS PendingChanges
FROM CHANGETABLE(CHANGES dbo.SyncTable, 0) AS CT;&lt;/LI-CODE&gt;
&lt;H3&gt;Why This Matters&lt;/H3&gt;
&lt;P&gt;A very large backlog may indicate:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Synchronization delays&lt;/LI&gt;
&lt;LI&gt;Metadata accumulation&lt;/LI&gt;
&lt;LI&gt;Enumeration pressure&lt;/LI&gt;
&lt;LI&gt;Increased risk of governance-related failures&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;3. Review Change Tracking Metadata&lt;/H2&gt;
&lt;LI-CODE lang="sql"&gt;--Run to UserDB
SELECT
  OBJECT_NAME(object_id) AS TableName,
    begin_version,
    min_valid_version,
    cleanup_version
FROM sys.change_tracking_tables
WHERE object_id = OBJECT_ID('dbo.SyncTable');&lt;/LI-CODE&gt;
&lt;H3&gt;Why This Matters&lt;/H3&gt;
&lt;P&gt;This information helps determine whether Change Tracking metadata is growing faster than cleanup processes can manage.&lt;/P&gt;
&lt;H2&gt;4. Validate Database Service Tier&lt;/H2&gt;
&lt;LI-CODE lang="sql"&gt;-- Run to UserDB
SELECT 
 database_id, 
 edition, 
 service_objective, 
 elastic_pool_name 
FROM sys.database_service_objectives;&lt;/LI-CODE&gt;
&lt;H3&gt;Why This Matters&lt;/H3&gt;
&lt;P&gt;Resource limitations associated with a database service tier may contribute to synchronization instability under heavy workloads.&lt;/P&gt;
&lt;H2&gt;5. Check for Resource Governance Events&lt;/H2&gt;
&lt;P&gt;Run the following query from the &lt;STRONG&gt;master database&lt;/STRONG&gt; of the Azure SQL logical server.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT TOP 20 
	end_time, 
	event_type, 
	event_subtype_desc, 
	description 
FROM sys.event_log 
WHERE event_type = 'connection'   
	AND event_subtype_desc = 'killed_by_governance'   
	AND end_time &amp;gt; DATEADD(hour, -24, GETUTCDATE()) 
ORDER BY end_time DESC;&lt;/LI-CODE&gt;
&lt;H3&gt;Why This Matters&lt;/H3&gt;
&lt;P&gt;This query can reveal whether Azure SQL Database terminated operations because they exceeded governance thresholds.&lt;/P&gt;
&lt;P&gt;Examples include:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Long-running synchronization queries&lt;/LI&gt;
&lt;LI&gt;Excessive CPU consumption&lt;/LI&gt;
&lt;LI&gt;Excessive IO workload&lt;/LI&gt;
&lt;LI&gt;Large Change Tracking enumeration operations&lt;/LI&gt;
&lt;/UL&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;Note:&lt;/STRONG&gt; sys.event_log is available only from the master database.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H2&gt;6. Identify Large Tables&lt;/H2&gt;
&lt;LI-CODE lang="sql"&gt;SELECT
    t.name AS TableName,
    SUM(p.rows) AS RowCounts
FROM sys.tables t
INNER JOIN sys.partitions p
    ON t.object_id = p.object_id
WHERE p.index_id IN (0,1)
GROUP BY t.name
ORDER BY RowCounts DESC;&lt;/LI-CODE&gt;
&lt;H3&gt;Why This Matters&lt;/H3&gt;
&lt;P&gt;Large high-churn tables often generate substantial amounts of synchronization metadata and are frequently associated with Data Sync performance issues.&lt;/P&gt;
&lt;H2&gt;7. Review Change Tracking Across All Tables&lt;/H2&gt;
&lt;LI-CODE lang="sql"&gt;SELECT
    OBJECT_SCHEMA_NAME(object_id) AS SchemaName,
    OBJECT_NAME(object_id) AS TableName,
    begin_version,
    cleanup_version,
    min_valid_version
FROM sys.change_tracking_tables
ORDER BY TableName;&lt;/LI-CODE&gt;
&lt;H3&gt;Why This Matters&lt;/H3&gt;
&lt;P&gt;This query helps identify whether metadata growth is isolated to a single synchronized table or occurring across multiple tables.&lt;/P&gt;
&lt;H2&gt;Troubleshooting Checklist&lt;/H2&gt;
&lt;P&gt;When troubleshooting Azure SQL Data Sync failures:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Confirm Change Tracking is enabled.&lt;/LI&gt;
&lt;LI&gt;Identify the failing synchronized table.&lt;/LI&gt;
&lt;LI&gt;Measure synchronization backlog size.&lt;/LI&gt;
&lt;LI&gt;Review Change Tracking metadata.&lt;/LI&gt;
&lt;LI&gt;Check database service-tier configuration.&lt;/LI&gt;
&lt;LI&gt;Check Azure SQL governance events.&lt;/LI&gt;
&lt;LI&gt;Review table size and update patterns.&lt;/LI&gt;
&lt;LI&gt;Monitor resource utilization.&lt;/LI&gt;
&lt;LI&gt;Validate synchronization health following remediation.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;Root Cause Analysis&lt;/H1&gt;
&lt;P&gt;The investigation ultimately revealed several contributing factors:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;A large synchronization backlog accumulated over time.&lt;/LI&gt;
&lt;LI&gt;Change Tracking metadata continued to grow.&lt;/LI&gt;
&lt;LI&gt;Synchronization enumeration operations became increasingly resource intensive.&lt;/LI&gt;
&lt;LI&gt;Azure SQL Database resource governance began terminating long-running synchronization operations.&lt;/LI&gt;
&lt;LI&gt;Data Sync repeatedly retried synchronization and encountered the same failures.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;As a result, synchronization was unable to progress beyond the accumulated backlog and remained stuck in a failure cycle.&lt;/P&gt;
&lt;H1&gt;Resolution&lt;/H1&gt;
&lt;P&gt;The mitigation focused on reducing synchronization pressure and rebuilding synchronization state.&lt;/P&gt;
&lt;H3&gt;Recovery Approach&lt;/H3&gt;
&lt;OL&gt;
&lt;LI&gt;Remove the affected table from the Sync Group.&lt;/LI&gt;
&lt;LI&gt;Save synchronization configuration changes.&lt;/LI&gt;
&lt;LI&gt;Preserve business data through backups or archival.&lt;/LI&gt;
&lt;LI&gt;Reset or recreate the synchronized table when appropriate.&lt;/LI&gt;
&lt;LI&gt;Allow synchronization metadata cleanup.&lt;/LI&gt;
&lt;LI&gt;Re-add the table to the Sync Group.&lt;/LI&gt;
&lt;LI&gt;Trigger synchronization.&lt;/LI&gt;
&lt;LI&gt;Validate successful synchronization completion.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;Following this approach, synchronization resumed successfully without further failures.&lt;/P&gt;
&lt;H1&gt;Why the Resolution Works&lt;/H1&gt;
&lt;P&gt;This process addresses the underlying metadata problem rather than repeatedly retrying synchronization.&lt;/P&gt;
&lt;P&gt;Benefits include:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Cleanup of excessive synchronization metadata&lt;/LI&gt;
&lt;LI&gt;Elimination of accumulated backlog&lt;/LI&gt;
&lt;LI&gt;Reset of synchronization state&lt;/LI&gt;
&lt;LI&gt;Fresh synchronization initialization&lt;/LI&gt;
&lt;LI&gt;Reduced enumeration workload&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;Technical Recommendations&lt;/H1&gt;
&lt;OL&gt;
&lt;LI&gt;Monitor synchronization health regularly.&lt;/LI&gt;
&lt;LI&gt;Track synchronization latency.&lt;/LI&gt;
&lt;LI&gt;Observe Data Sync metadata growth.&lt;/LI&gt;
&lt;LI&gt;Investigate synchronization failures early.&lt;/LI&gt;
&lt;LI&gt;Monitor DTU or vCore utilization.&lt;/LI&gt;
&lt;LI&gt;Review high-volume synchronized tables.&lt;/LI&gt;
&lt;LI&gt;Validate Change Tracking health periodically.&lt;/LI&gt;
&lt;LI&gt;Monitor retries and failed sync operations.&lt;/LI&gt;
&lt;LI&gt;Establish proactive alerting.&lt;/LI&gt;
&lt;LI&gt;Review synchronization design for large-scale workloads.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN style="color: rgb(30, 30, 30); font-size: 34px;"&gt;Common Error Messages&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;Error 40197&lt;/H2&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;The service has encountered an error processing your request.&lt;/P&gt;
&lt;P&gt;Please try again.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;Potential Causes&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;Transient platform interruption&lt;/LI&gt;
&lt;LI&gt;Resource-governance intervention&lt;/LI&gt;
&lt;LI&gt;Long-running synchronization operations&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Error 40549&lt;/H2&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Error code 40549&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;Potential Causes&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;Excessive resource consumption&lt;/LI&gt;
&lt;LI&gt;Long-running transactions&lt;/LI&gt;
&lt;LI&gt;Synchronization enumeration pressure&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Cannot Enumerate Changes at the RelationalSyncProvider&lt;/H2&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Cannot enumerate changes at the RelationalSyncProvider.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;Potential Causes&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;Change Tracking backlog growth&lt;/LI&gt;
&lt;LI&gt;Excessive synchronization metadata&lt;/LI&gt;
&lt;LI&gt;Resource-governance intervention&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;Lessons Learned&lt;/H1&gt;
&lt;UL&gt;
&lt;LI&gt;Monitor Data Sync metadata growth proactively.&lt;/LI&gt;
&lt;LI&gt;Investigate synchronization delays before backlog accumulates.&lt;/LI&gt;
&lt;LI&gt;High-volume transactional tables require closer monitoring.&lt;/LI&gt;
&lt;LI&gt;Resource governance can significantly impact synchronization workloads.&lt;/LI&gt;
&lt;LI&gt;Reinitializing synchronization state may be necessary when metadata growth becomes excessive.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;Key Takeaways&lt;/H1&gt;
&lt;UL&gt;
&lt;LI&gt;Azure SQL Data Sync depends heavily on Change Tracking metadata.&lt;/LI&gt;
&lt;LI&gt;Large synchronization backlogs can cause expensive enumeration operations.&lt;/LI&gt;
&lt;LI&gt;Errors 40197 and 40549 may indicate resource-governance interruptions.&lt;/LI&gt;
&lt;LI&gt;Large metadata accumulation can trigger synchronization failures.&lt;/LI&gt;
&lt;LI&gt;Monitoring synchronization health is essential.&lt;/LI&gt;
&lt;LI&gt;High-volume tables require ongoing review.&lt;/LI&gt;
&lt;LI&gt;Resetting synchronization state can be an effective recovery mechanism.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;Conclusion&lt;/H1&gt;
&lt;P&gt;Azure SQL Data Sync remains a powerful solution for synchronizing data across Azure SQL Database environments. However, synchronization metadata and Change Tracking backlog growth can gradually evolve into serious operational challenges when left unchecked.&lt;/P&gt;
&lt;P&gt;In this troubleshooting scenario, synchronization failures were ultimately traced to a combination of excessive Change Tracking backlog growth and Azure SQL Database resource-governance limits. By identifying the affected table, measuring backlog pressure using targeted T-SQL queries, evaluating governance events, and reinitializing synchronization state, synchronization was successfully restored and stabilized.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The key lesson is simple: proactive monitoring of Change Tracking metadata, synchronization backlog size, and Azure SQL workload health can prevent many Data Sync outages before they become business-impacting incidents.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 18 Jun 2026 21:01:11 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/troubleshooting-azure-sql-data-sync-failures-caused-by-large/ba-p/4529337</guid>
      <dc:creator>Mohamed_Baioumy_MSFT</dc:creator>
      <dc:date>2026-06-18T21:01:11Z</dc:date>
    </item>
    <item>
      <title>Lessons Learned #540:Bulk Insert Throughput in Azure SQL Hyperscale with Partitioned Heap Tables</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/lessons-learned-540-bulk-insert-throughput-in-azure-sql/ba-p/4528842</link>
      <description>&lt;P&gt;In this lesson learned, I would like to share an interesting scenario working on a service request where our customer was running a high-volume data load process in Azure SQL Database Hyperscale. The workload was based on a common pattern:&lt;/P&gt;
&lt;OL data-spread="false"&gt;
&lt;LI&gt;Recreate a staging table.&lt;/LI&gt;
&lt;LI&gt;Load a large number of rows using bulk insert.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;The bulk insert showed unstable execution times and became the main area to investigate.&lt;/P&gt;
&lt;P&gt;The process was loading a very large number of rows into an Azure SQL Database Hyperscale database. The process used a staging table that was initially loaded as a heap. The main concern was the inconsistent execution time during the load process.&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;Why Manually Adding Data Files Was Not the Right Direction&lt;/H2&gt;
&lt;P&gt;In Azure SQL Database Hyperscale, the storage architecture is different from a traditional SQL Server deployment. The data layout and storage management are handled internally by the service.&lt;/P&gt;
&lt;P&gt;Because of this architecture, manually creating or pre-allocating multiple data files is not the same tuning option that we may consider in SQL Server on-premises or SQL Server running on Azure Virtual Machines.&lt;/P&gt;
&lt;P&gt;For this reason, the troubleshooting focus moved from manual file layout configuration to the actual workload pattern, waits, concurrency, batch size, and staging table design.&lt;/P&gt;
&lt;H2&gt;What We Observed&lt;/H2&gt;
&lt;P&gt;During the bulk insert phase, waits such as PAGELATCH_EX were observed. Since the staging table was loaded as a heap and the clustered primary key was created only after the bulk insert completed, OPTIMIZE_FOR_SEQUENTIAL_KEY was not directly applicable to the bulk insert phase.&lt;/P&gt;
&lt;P&gt;This changed the direction of the investigation. Instead of focusing on last-page insert contention on an existing clustered index, the analysis moved toward heap insert behavior, allocation contention, concurrency, batch size, and whether a different staging table design could help.&lt;/P&gt;
&lt;H2&gt;First Recommendation: Start with Low-Impact Changes&lt;/H2&gt;
&lt;P&gt;Before changing the table design, the first recommendation was to test the least intrusive changes:&lt;/P&gt;
&lt;OL data-spread="false"&gt;
&lt;LI&gt;Reduce the number of concurrent bulk insert sessions.&lt;/LI&gt;
&lt;LI&gt;Increase the batch size, for example from 10,000 rows to 50,000 or 100,000 rows.&lt;/LI&gt;
&lt;LI&gt;Test TABLOCK on the dedicated heap staging table.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;The goal was to avoid assuming that more concurrency would always reduce the total execution time. In some high-volume load scenarios, excessive concurrency may increase contention and make the process less stable.&lt;/P&gt;
&lt;H2&gt;The Interesting Design Option: Partitioned Heap Staging Table&lt;/H2&gt;
&lt;P&gt;One of the most interesting design options was to evaluate a partitioned heap staging table.&lt;/P&gt;
&lt;P&gt;The idea is simple: instead of loading all rows into a non-partitioned heap staging table, the staging table can be created on the same partition scheme used by the target table, using the same partitioning column.&lt;/P&gt;
&lt;P&gt;This does not mean that a partitioned heap will always be faster. However, it can be a useful design option when:&lt;/P&gt;
&lt;OL data-spread="false"&gt;
&lt;LI&gt;The bulk load phase is affected by allocation or latch contention.&lt;/LI&gt;
&lt;LI&gt;Concurrent load processes can naturally distribute rows across different partition ranges.&lt;/LI&gt;
&lt;LI&gt;The staging table is used only as an intermediate structure.Lessons Learned&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;The main lessons from this scenario were:&lt;/P&gt;
&lt;OL data-spread="false"&gt;
&lt;LI&gt;In Azure SQL Database Hyperscale, manually managing multiple data files is not the right tuning direction.&lt;/LI&gt;
&lt;LI&gt;PAGELATCH_EX during heap loading may point to concurrency or allocation-related contention.&lt;/LI&gt;
&lt;LI&gt;Reducing concurrency can sometimes improve total throughput.&lt;/LI&gt;
&lt;LI&gt;Larger batch sizes may provide better results than many small batches.&lt;/LI&gt;
&lt;LI&gt;TABLOCK on a dedicated heap staging table is a low-impact test worth evaluating.&lt;/LI&gt;
&lt;LI&gt;A partitioned heap staging table can be a valid second-phase design option when the load can be distributed across partition ranges.&lt;/LI&gt;
&lt;LI&gt;The best approach is to test small, measurable changes before introducing architectural redesigns.&lt;/LI&gt;
&lt;/OL&gt;
&lt;H2&gt;Final Thoughts&lt;/H2&gt;
&lt;P&gt;A partitioned heap staging table can be a powerful option, but only when it is tested carefully and when the workload pattern can benefit from partition distribution.&lt;/P&gt;</description>
      <pubDate>Wed, 17 Jun 2026 12:12:44 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/lessons-learned-540-bulk-insert-throughput-in-azure-sql/ba-p/4528842</guid>
      <dc:creator>Jose_Manuel_Jurado</dc:creator>
      <dc:date>2026-06-17T12:12:44Z</dc:date>
    </item>
    <item>
      <title>Why do I see many VDI_CLIENT_WORKER sessions in Azure SQL Database — and do they impact performance?</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/why-do-i-see-many-vdi-client-worker-sessions-in-azure-sql/ba-p/4523817</link>
      <description>&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Sometimes you’ll notice many sessions showing the command &lt;STRONG&gt;VDI_CLIENT_WORKER&lt;/STRONG&gt; in Azure SQL Database—often around &lt;STRONG&gt;scaling, replica/copy workflows, or internal seeding operations&lt;/STRONG&gt;. These sessions can look alarming, especially during a performance investigation, but they are typically &lt;STRONG&gt;internal background workers&lt;/STRONG&gt;. This post explains how to recognize them, what’s safe to do (and what isn’t), and how to focus on the real bottlenecks like &lt;STRONG&gt;blocking/deadlocks&lt;/STRONG&gt; or &lt;STRONG&gt;log rate throttling&lt;/STRONG&gt; when you’re troubleshooting slowness.&lt;/P&gt;
&lt;H1&gt;Why you might see VDI_CLIENT_WORKER sessions in Azure SQL Database&lt;/H1&gt;
&lt;img /&gt;
&lt;H2&gt;The symptom&lt;/H2&gt;
&lt;P&gt;You run a session query (for example, using sys.dm_exec_requests or a monitoring tool) and observe:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Many sessions&lt;/STRONG&gt; with command text &lt;STRONG&gt;VDI_CLIENT_WORKER&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;They may appear to be “stuck,” persist longer than expected, and &lt;STRONG&gt;can’t be killed&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Teams may worry these sessions are “the cause” of slowness&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;Why it shows up in Azure SQL&lt;/H2&gt;
&lt;P&gt;In Azure SQL, VDI_CLIENT_* wait types and VDI_CLIENT_WORKER sessions are commonly associated with platform operations that involve &lt;STRONG&gt;copying/seeding&lt;/STRONG&gt;—for example:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Scaling operations (service objective changes)&lt;/LI&gt;
&lt;LI&gt;Geo-replication / copy workflows&lt;/LI&gt;
&lt;LI&gt;Replica seeding-like behaviors&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Important: The presence of these sessions&amp;nbsp;&lt;STRONG&gt;does not automatically mean they are the bottleneck&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;How to validate whether VDI_CLIENT_WORKER is benign?&lt;/H1&gt;
&lt;H2&gt;1) Correlate to recent platform operations.&lt;/H2&gt;
&lt;P&gt;Ask: did you recently perform (or did the platform perform) one of these?&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Scale up/down.&lt;/LI&gt;
&lt;LI&gt;Creation of replicas / geo-secondary operations.&lt;/LI&gt;
&lt;LI&gt;Any database copy-like workflow.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;If yes, it’s a strong indicator you’re seeing background workers tied to that lifecycle event.&lt;/P&gt;
&lt;H2&gt;2) Check whether they consume resources.&lt;/H2&gt;
&lt;P&gt;A practical approach:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Look for CPU/IO/log pressure at the database level.&lt;/LI&gt;
&lt;LI&gt;Compare the timing of slowness reports with spikes in waits/locks/log write percentage.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;If these sessions show &lt;STRONG&gt;minimal resource consumption&lt;/STRONG&gt; and are just “present,” treat them as background noise while you investigate real contention.&lt;/P&gt;
&lt;H2&gt;3) Don’t try to kill them!&lt;/H2&gt;
&lt;P&gt;These sessions are typically &lt;STRONG&gt;system/internal&lt;/STRONG&gt;. Attempts to kill them may fail or be ineffective—and generally aren’t recommended.&lt;/P&gt;
&lt;H2&gt;4) If you need them to disappear.&lt;/H2&gt;
&lt;P&gt;In many cases, these internal workers naturally age out. If they remain visible and you need a cleanup path, operational actions like &lt;STRONG&gt;failover/restart&lt;/STRONG&gt; may clear stale workers (use change control / maintenance windows as appropriate for your environment).&lt;BR /&gt;&lt;EM&gt;(This is a practical operational observation; always weigh downtime/impact.)&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;When performance is actually slow: focus on what usually hurts.&lt;/H1&gt;
&lt;P&gt;In many real-world incidents, the main causes of slowness are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Blocking chains / deadlocks.&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Transaction log rate throttling (LOG_RATE_GOVERNOR)&lt;/STRONG&gt; during heavy DML.&lt;/LI&gt;
&lt;LI&gt;Hot queries running concurrently and contending on the same objects.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;Key takeaways&lt;/H1&gt;
&lt;UL&gt;
&lt;LI&gt;Seeing many VDI_CLIENT_WORKER sessions is often &lt;STRONG&gt;expected&lt;/STRONG&gt; around platform copy/seeding workflows and doesn’t automatically indicate a bottleneck.&lt;/LI&gt;
&lt;LI&gt;Don’t attempt to kill system/internal workers; instead, validate resource impact and focus on actual bottlenecks.&lt;/LI&gt;
&lt;LI&gt;For real slowness, prioritize diagnosing &lt;STRONG&gt;blocking/deadlocks&lt;/STRONG&gt; and &lt;STRONG&gt;LOG_RATE_GOVERNOR&lt;/STRONG&gt;-driven DML throttling.&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Fri, 29 May 2026 06:52:21 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/why-do-i-see-many-vdi-client-worker-sessions-in-azure-sql/ba-p/4523817</guid>
      <dc:creator>Ashriti_Jamwal</dc:creator>
      <dc:date>2026-05-29T06:52:21Z</dc:date>
    </item>
    <item>
      <title>Unexpected PITR Charges from restorableDroppedDatabases After BC → Hyperscale Migration</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/unexpected-pitr-charges-from-restorabledroppeddatabases-after-bc/ba-p/4519768</link>
      <description>&lt;P&gt;&lt;STRONG&gt;Why This Behavior Is by Design&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;When migrating an Azure SQL Database from &lt;STRONG&gt;Business Critical (BC)&lt;/STRONG&gt; to &lt;STRONG&gt;Hyperscale&lt;/STRONG&gt; using a &lt;STRONG&gt;manual cutover&lt;/STRONG&gt;, some customers notice &lt;STRONG&gt;unexpected Point-in-Time Restore (PITR) backup storage charges&lt;/STRONG&gt; appearing under the following resource:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;/Microsoft.Sql/servers/&amp;lt;server&amp;gt;/restorableDroppedDatabases/&amp;lt;database&amp;gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;At first glance, this can be confusing—especially when:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;No &lt;STRONG&gt;customer-initiated drop or delete&lt;/STRONG&gt; was performed&lt;/LI&gt;
&lt;LI&gt;The database is &lt;STRONG&gt;online and healthy post-migration&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Test migrations may not have shown similar charges&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This post explains &lt;STRONG&gt;why this happens&lt;/STRONG&gt;, &lt;STRONG&gt;why it is expected by design&lt;/STRONG&gt;, and &lt;STRONG&gt;how these charges naturally expire&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H2&gt;The Observed Scenario&lt;/H2&gt;
&lt;P&gt;After a &lt;STRONG&gt;BC → Hyperscale manual cutover&lt;/STRONG&gt;, customers may see PITR charges tied to:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;restorableDroppedDatabases/&amp;lt;database-name&amp;gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Despite the database being active and available in Hyperscale, these charges start appearing&amp;nbsp;&lt;STRONG&gt;immediately after the migration cutover&lt;/STRONG&gt; and gradually decrease over time.&lt;/P&gt;
&lt;H2&gt;Why Does the Database Appear as “Dropped”?&lt;/H2&gt;
&lt;P&gt;During a &lt;STRONG&gt;manual cutover migration&lt;/STRONG&gt;, Azure SQL performs an &lt;STRONG&gt;internal platform-driven workflow&lt;/STRONG&gt; to complete the transition between architectures.&lt;/P&gt;
&lt;P&gt;From a control-plane perspective:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The &lt;STRONG&gt;source Business Critical logical database is internally dropped&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;This drop is &lt;STRONG&gt;not initiated by the customer&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;It is a &lt;STRONG&gt;required system step&lt;/STRONG&gt; to complete the Hyperscale migration&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Telemetry confirms that the migration workflow transitions through states such as:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Internal drop of the source physical and logical database&lt;/LI&gt;
&lt;LI&gt;Cleanup of metadata and completion of the migration&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This entire sequence completes within seconds and is fully platform managed.&lt;/P&gt;
&lt;H2&gt;Why Are Backup Charges Generated?&lt;/H2&gt;
&lt;P&gt;Although the &lt;STRONG&gt;source BC database is internally dropped&lt;/STRONG&gt;, its &lt;STRONG&gt;pre-migration PITR backups are still retained&lt;/STRONG&gt; according to the configured backup retention period.&lt;/P&gt;
&lt;P&gt;Here’s the key point:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Backups taken before upgrading to Hyperscale are retained and billed using the dropped-database backup billing model.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Because the source database is now considered&amp;nbsp;&lt;STRONG&gt;dropped (from the BC perspective)&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The &lt;STRONG&gt;1× database-size discount no longer applies&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;The &lt;STRONG&gt;full data file size&lt;/STRONG&gt; is added to the billable backup size&lt;/LI&gt;
&lt;LI&gt;Charges appear under restorableDroppedDatabases&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This behavior is explicitly documented as&amp;nbsp;&lt;STRONG&gt;expected&lt;/STRONG&gt; in internal Azure SQL billing guidance.&lt;/P&gt;
&lt;H2&gt;Why Do Charges Decrease Over Time?&lt;/H2&gt;
&lt;P&gt;These charges are &lt;STRONG&gt;not permanent&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;They:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Decrease daily&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Continue only while the &lt;STRONG&gt;pre-migration PITR backups are retained&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Automatically stop once the retention window expires&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;In practical terms:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Charges stop when: days_since_migration &amp;gt; configured_backup_retention_days&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;No cleanup action is required from the customer—the platform handles this automatically.&lt;/P&gt;
&lt;H2&gt;Why Didn’t Test Migrations Show Similar Charges?&lt;/H2&gt;
&lt;P&gt;In many reported cases, &lt;STRONG&gt;test or smaller databases&lt;/STRONG&gt; migrated using the same method did &lt;STRONG&gt;not&lt;/STRONG&gt; generate noticeable charges.&lt;/P&gt;
&lt;P&gt;This can be explained by two documented optimizations:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Backup size threshold&lt;/STRONG&gt; – very small backup footprints are not charged&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Low activity optimization&lt;/STRONG&gt; – inactive or low-change databases generate fewer snapshots&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;As a result, smaller or lightly used test databases may fall &lt;STRONG&gt;below the billing threshold&lt;/STRONG&gt;, while larger production databases do not.&lt;/P&gt;
&lt;H2&gt;Is This a Billing Error or Credit Scenario?&lt;/H2&gt;
&lt;P&gt;&lt;STRONG&gt;No.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Although the operation is platform-driven:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The behavior is &lt;STRONG&gt;by design&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;The charges are for &lt;STRONG&gt;temporary retention of valid PITR backups&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;They naturally expire based on retention&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Therefore, this scenario is &lt;STRONG&gt;not considered a billing defect&lt;/STRONG&gt; and &lt;STRONG&gt;does not typically warrant credits&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H2&gt;How Can Customers Reduce Charges Faster?&lt;/H2&gt;
&lt;P&gt;If needed, customers can:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Reduce the PITR backup retention period&lt;/STRONG&gt; (minimum is 1 day)&lt;/LI&gt;
&lt;LI&gt;Wait up to &lt;STRONG&gt;24 hours&lt;/STRONG&gt; for billing to reflect the change&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This shortens how long the pre-migration backups are retained and billed.&lt;/P&gt;
&lt;H2&gt;FAQ – restorableDroppedDatabases Charges After BC → Hyperscale Migration&lt;/H2&gt;
&lt;H3&gt;&lt;STRONG&gt;Q1: Why am I seeing PITR charges for restorableDroppedDatabases when my database is still online?&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; During a &lt;STRONG&gt;Business Critical → Hyperscale manual cutover&lt;/STRONG&gt;, Azure SQL &lt;STRONG&gt;internally drops the source BC database&lt;/STRONG&gt; as part of the migration workflow. While the Hyperscale database is active and healthy, the &lt;STRONG&gt;pre‑migration BC backups are retained&lt;/STRONG&gt; and billed under restorableDroppedDatabases.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Q2: Did the customer initiate a drop or delete operation?&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; No. This drop is &lt;STRONG&gt;platform‑driven&lt;/STRONG&gt; and required to complete the migration. It is not initiated by the customer.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Q3: What exactly is being billed?&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; The charges are for &lt;STRONG&gt;Point‑in‑Time Restore (PITR) backups taken before the migration&lt;/STRONG&gt;. These backups are retained according to the configured backup retention period and are billed using the &lt;STRONG&gt;dropped database billing model&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Q4: Why does the cost appear higher than expected?&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; Once a database is considered “dropped” (from the BC perspective), the &lt;STRONG&gt;1× database-size discount no longer applies&lt;/STRONG&gt;, and the &lt;STRONG&gt;full data file size&lt;/STRONG&gt; is included in the billable backup size.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Q5: Will these charges continue indefinitely?&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; No. The charges &lt;STRONG&gt;decrease daily&lt;/STRONG&gt; and &lt;STRONG&gt;automatically stop&lt;/STRONG&gt; once the pre‑migration backups expire based on the configured PITR retention period.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Q6: Why didn’t this happen with smaller or test databases?&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; Smaller or low‑activity databases may fall &lt;STRONG&gt;below the backup billing threshold&lt;/STRONG&gt;, or benefit from &lt;STRONG&gt;low‑activity snapshot optimizations&lt;/STRONG&gt;, resulting in no visible charges.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Q7: Is this a billing bug or credit-worthy scenario?&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; No. This behavior is &lt;STRONG&gt;by design and expected&lt;/STRONG&gt;. The charges reflect valid backup retention and do not typically qualify for credits.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Q8: Can the customer reduce these charges sooner?&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; Yes. The customer can &lt;STRONG&gt;reduce the PITR backup retention period&lt;/STRONG&gt; (minimum 1 day). Billing changes usually reflect within &lt;STRONG&gt;up to 24 hours&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H2&gt;Key Takeaways&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;The behavior is&amp;nbsp;&lt;STRONG&gt;expected and by design&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Charges come from&amp;nbsp;&lt;STRONG&gt;pre-migration BC backups&lt;/STRONG&gt;, not the active Hyperscale database&lt;/LI&gt;
&lt;LI&gt;The database was&amp;nbsp;&lt;STRONG&gt;internally dropped as part of migration&lt;/STRONG&gt;, not by the customer&lt;/LI&gt;
&lt;LI&gt;Charges&amp;nbsp;&lt;STRONG&gt;decrease daily and stop automatically&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;No action is required unless the customer wants to reduce retention early&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Final Note&lt;/H2&gt;
&lt;P&gt;As of the time of writing, &lt;STRONG&gt;this behavior is not clearly described in public customer-facing documentation&lt;/STRONG&gt;, which explains why it often appears unexpected. Awareness of this mechanism can help set correct expectations when planning BC → Hyperscale manual cutover migrations.&lt;/P&gt;</description>
      <pubDate>Thu, 14 May 2026 14:01:54 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/unexpected-pitr-charges-from-restorabledroppeddatabases-after-bc/ba-p/4519768</guid>
      <dc:creator>Mohamed_Baioumy_MSFT</dc:creator>
      <dc:date>2026-05-14T14:01:54Z</dc:date>
    </item>
    <item>
      <title>Azure SQL BACPAC Export Failure with CDC &amp; db_cdcreader (SQL71501)</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/azure-sql-bacpac-export-failure-with-cdc-db-cdcreader-sql71501/ba-p/4517286</link>
      <description>&lt;H2&gt;Overview&lt;/H2&gt;
&lt;P&gt;Exporting an Azure SQL Database to a BACPAC using &lt;STRONG&gt;SqlPackage / SSMS&lt;/STRONG&gt; may fail when &lt;STRONG&gt;Change Data Capture (CDC)&lt;/STRONG&gt; is enabled and database users (or Entra groups) are assigned to CDC-related roles such as db_cdcreader.&lt;/P&gt;
&lt;P&gt;A common error observed:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Error SQL71501: Error validating element:&lt;/P&gt;
&lt;P&gt;Role Membership: has an unresolved reference to Role [db_cdcreader].&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This issue can be confusing because:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The database is healthy&lt;/LI&gt;
&lt;LI&gt;CDC is functioning correctly&lt;/LI&gt;
&lt;LI&gt;The error occurs only during export&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Scenario&lt;/H2&gt;
&lt;P&gt;From a real customer case:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Azure SQL Database with &lt;STRONG&gt;CDC enabled&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;An &lt;STRONG&gt;Entra (AAD) group&lt;/STRONG&gt; added to db_cdcreader&lt;/LI&gt;
&lt;LI&gt;Export attempted via &lt;STRONG&gt;SqlPackage (v170+)&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Export fails during &lt;STRONG&gt;schema validation phase&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Root Cause Explained&lt;/H2&gt;
&lt;H3&gt;1. SqlPackage performs strict schema modeling&lt;/H3&gt;
&lt;P&gt;During export, SqlPackage (via &lt;STRONG&gt;DacFx&lt;/STRONG&gt;) builds a &lt;STRONG&gt;logical schema model&lt;/STRONG&gt; of the database.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Every object must be fully resolvable&lt;/LI&gt;
&lt;LI&gt;Roles and &lt;STRONG&gt;role memberships are validated&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Any missing/unsupported object → export fails&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This is why the error appears as:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;SQL71501 – unresolved reference&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;2. CDC introduces system-managed objects&lt;/H3&gt;
&lt;P&gt;When CDC is enabled, SQL automatically creates:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;cdc schema&lt;/LI&gt;
&lt;LI&gt;System tables&lt;/LI&gt;
&lt;LI&gt;Special roles:
&lt;UL&gt;
&lt;LI&gt;db_cdcreader&lt;/LI&gt;
&lt;LI&gt;cdc_admin&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;These objects are&amp;nbsp;&lt;STRONG&gt;not treated as regular user-defined objects&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;They are system-managed&lt;/LI&gt;
&lt;LI&gt;Some are implicitly created&lt;/LI&gt;
&lt;LI&gt;Some are &lt;STRONG&gt;not fully modeled/exported by DacFx&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;3. Role membership is the breaking point&lt;/H3&gt;
&lt;P&gt;The failure does &lt;STRONG&gt;not happen because the role exists&lt;/STRONG&gt;&lt;BR /&gt;It happens because:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The&amp;nbsp;&lt;STRONG&gt;role membership exists&lt;/STRONG&gt; (e.g., Entra group → db_cdcreader)&lt;/LI&gt;
&lt;LI&gt;But the&amp;nbsp;&lt;STRONG&gt;role itself is not included or resolved in the export model&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Result:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Membership → cannot resolve target role → validation failure (SQL71501)&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This behavior aligns with documented patterns where &lt;STRONG&gt;CDC roles are excluded or not recognized during BACPAC export.&lt;/STRONG&gt;&lt;/P&gt;
&lt;H2&gt;Reproducing the Issue&lt;/H2&gt;
&lt;P&gt;You are likely impacted if:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;CDC is enabled&lt;/LI&gt;
&lt;LI&gt;Users or Entra groups are assigned to:
&lt;UL&gt;
&lt;LI&gt;db_cdcreader&lt;/LI&gt;
&lt;LI&gt;cdc_admin&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;Export is attempted via:
&lt;UL&gt;
&lt;LI&gt;SqlPackage&lt;/LI&gt;
&lt;LI&gt;SSMS “Export Data-tier Application”&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Workarounds&lt;/H2&gt;
&lt;H3&gt;Option 1: Temporarily remove role membership&lt;/H3&gt;
&lt;P&gt;Remove the CDC role membership before export:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;ALTER ROLE db_cdcreader DROP MEMBER [your_user_or_group];&lt;/LI-CODE&gt;
&lt;P&gt;Run export, then reassign:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;ALTER ROLE db_cdcreader ADD MEMBER [your_user_or_group];&lt;/LI-CODE&gt;
&lt;P&gt;This is the&amp;nbsp;&lt;STRONG&gt;simplest and most reliable workaround&lt;/STRONG&gt;&lt;BR /&gt;Confirmed in Microsoft Q&amp;amp;A guidance for CDC roles&lt;/P&gt;
&lt;H3&gt;Option 2: Export from a cleaned database copy&lt;/H3&gt;
&lt;P&gt;If you cannot modify production (e.g., tooling restrictions):&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Create a database copy&lt;/LI&gt;
&lt;LI&gt;Remove CDC-related role memberships&lt;/LI&gt;
&lt;LI&gt;Export from the copy&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;Recommended when:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Using automation tools (e.g., Commvault)&lt;/LI&gt;
&lt;LI&gt;Production changes are restricted&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Option 3: Cleanup unsupported references&lt;/H3&gt;
&lt;P&gt;General best practice:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Remove unsupported / system-bound references before export&lt;/LI&gt;
&lt;LI&gt;Especially:
&lt;UL&gt;
&lt;LI&gt;CDC role memberships&lt;/LI&gt;
&lt;LI&gt;Legacy system objects&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Option 4: Use SqlPackage with ExtractAllTableData=True&lt;/H3&gt;
&lt;P&gt;Another practical workaround is to leverage the SqlPackage option &lt;STRONG&gt;ExtractAllTableData=True&lt;/STRONG&gt;, which allows you to extract all data from all user tables.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;When set to &lt;STRONG&gt;True&lt;/STRONG&gt;:
&lt;UL&gt;
&lt;LI&gt;Data is extracted from&amp;nbsp;&lt;STRONG&gt;all user tables&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;You cannot specify individual tables&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;When set to &lt;STRONG&gt;False &lt;/STRONG&gt;(default):
&lt;UL&gt;
&lt;LI&gt;You can selectively extract data from&amp;nbsp;&lt;STRONG&gt;specific tables only&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;This reduces exposure to unsupported or problematic objects during validation&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Example&lt;/P&gt;
&lt;LI-CODE lang=""&gt;SqlPackage /Action:Extract 
  /SourceServerName:&amp;lt;server&amp;gt; 
  /SourceDatabaseName:&amp;lt;database&amp;gt; 
  /TargetFile:&amp;lt;output.bacpac&amp;gt; 
  /p:ExtractAllTableData=True&lt;/LI-CODE&gt;
&lt;H3&gt;&lt;STRONG&gt;When to use this option&lt;/STRONG&gt;&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;When the export fails due to &lt;STRONG&gt;CDC roles or related schema validation issues (SQL71501)&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;As a targeted workaround when full export is blocked&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Important Considerations&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;This is &lt;STRONG&gt;not a runtime database issue&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;It is a &lt;STRONG&gt;schema validation limitation in DacFx / SqlPackage&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;CDC itself &lt;STRONG&gt;is supported&lt;/STRONG&gt;, but:
&lt;UL&gt;
&lt;LI&gt;Certain &lt;STRONG&gt;security objects are not fully exportable&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Key Takeaways&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;SQL71501 during export is often a &lt;STRONG&gt;model validation issue&lt;/STRONG&gt;, not a data issue&lt;/LI&gt;
&lt;LI&gt;CDC roles (db_cdcreader, cdc_admin) can break export due to &lt;STRONG&gt;partial modeling&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;The failure is triggered by &lt;STRONG&gt;role membership&lt;/STRONG&gt;, not CDC itself&lt;/LI&gt;
&lt;LI&gt;Workarounds involve:
&lt;UL&gt;
&lt;LI&gt;Removing memberships&lt;/LI&gt;
&lt;LI&gt;Exporting from a cleaned copy&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Wed, 20 May 2026 13:03:36 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/azure-sql-bacpac-export-failure-with-cdc-db-cdcreader-sql71501/ba-p/4517286</guid>
      <dc:creator>Mohamed_Baioumy_MSFT</dc:creator>
      <dc:date>2026-05-20T13:03:36Z</dc:date>
    </item>
    <item>
      <title>Azure SQL Database BACPAC Export Stuck with Private Link and Resource Locks</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/azure-sql-database-bacpac-export-stuck-with-private-link-and/ba-p/4515271</link>
      <description>&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;Symptoms&lt;/STRONG&gt;&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;In real customer environments, this issue commonly appears in the following forms:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;An export job is stuck at &lt;STRONG&gt;Running (100%)&lt;/STRONG&gt; and never completes, blocking scheduled or automated export jobs.&lt;/LI&gt;
&lt;LI&gt;A BACPAC export operation is canceled (via Azure Portal or CLI), but remains in &lt;STRONG&gt;CancelInProgress&lt;/STRONG&gt;&lt;U&gt; &lt;/U&gt;for an extended period (for example, more than n hours) without progress.&lt;/LI&gt;
&lt;LI&gt;Multiple databases are impacted, where previous export operations remain stuck, preventing new export requests from starting.&lt;/LI&gt;
&lt;LI&gt;New export attempts fail with the following error: &lt;STRONG style="color: rgb(30, 30, 30);"&gt;"&lt;SPAN class="lia-text-color-8"&gt;There is an import or export operation in progress on the database&lt;/SPAN&gt;."&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;These scenarios can significantly impact automation pipelines, backup strategies, and overall operational workflows.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;Example from Azure Portal&lt;/STRONG&gt;&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;The following example shows an export operation stuck during cancellation, along with the corresponding error message:&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;img&gt;&lt;EM&gt;Figure 1: Export operation stuck in CancelInProgress and error indicating another operation is in progress&lt;/EM&gt;&lt;/img&gt;
&lt;H6&gt;&amp;nbsp;&lt;/H6&gt;
&lt;H6&gt;&amp;nbsp;&lt;/H6&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H6&gt;&amp;nbsp;&lt;/H6&gt;
&lt;H6&gt;&lt;U&gt;&lt;STRONG&gt;Root Cause&lt;/STRONG&gt;&lt;/U&gt;&lt;/H6&gt;
&lt;P&gt;When you enable the&amp;nbsp;&lt;STRONG&gt;Use private link&lt;/STRONG&gt; option during import or export, the service automatically creates temporary, service-managed private endpoints to securely connect the Azure SQL Database to the target Storage Account. You must manually approve the private endpoint for both the Azure SQL logical server and the Azure Blob storage account in separate steps. This tutorial includes the details.&lt;/P&gt;
&lt;P&gt;These private endpoints are automatically deleted during the cleanup phase, which occurs when the export operation completes or is canceled.&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;However, if a&amp;nbsp;&lt;STRONG&gt;Delete lock&lt;/STRONG&gt; exists on any of the following resources:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Azure SQL Logical Server / Database&lt;/LI&gt;
&lt;LI&gt;Azure Storage Account&lt;/LI&gt;
&lt;LI&gt;Resource Group (might be an inherited lock)&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;As a result:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The service cannot delete the service-managed private endpoints&lt;/LI&gt;
&lt;LI&gt;Backend cleanup operations fail to complete&lt;/LI&gt;
&lt;LI&gt;The export/cancel operation remains stuck in an intermediate state&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This leads to scenarios where:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Export appearing completed (100%) but not finalized&lt;/LI&gt;
&lt;LI&gt;Cancellation stuck in CancelInProgress&lt;/LI&gt;
&lt;LI&gt;Further Import/Export operations are blocked&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This behavior is consistent with cases where resource locks prevent required cleanup operations: &lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/database/database-import-export-private-link?view=azuresql#limitations" target="_blank" rel="noopener"&gt;Import or Export a Database Using Private Link - Azure SQL Database | Microsoft Learn&lt;/A&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;img&gt;
&lt;P&gt;Figure 2: Limitation of using Private Link for Import/Export with resource locks applied&lt;/P&gt;
&lt;/img&gt;
&lt;H6&gt;&amp;nbsp;&lt;/H6&gt;
&lt;H6&gt;&amp;nbsp;&lt;/H6&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H6&gt;&lt;U&gt;&lt;STRONG&gt;Resolution&lt;/STRONG&gt;&lt;/U&gt;&lt;/H6&gt;
&lt;P&gt;To unblock the operation:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Remove the &lt;STRONG&gt;Delete lock&lt;/STRONG&gt; from the affected resources:
&lt;UL&gt;
&lt;LI&gt;Azure SQL Server / Database&lt;/LI&gt;
&lt;LI&gt;Azure Storage Account&lt;/LI&gt;
&lt;LI&gt;(Check Resource Group level for inherited locks)&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;Wait for the backend system to:
&lt;UL&gt;
&lt;LI&gt;Complete Private Endpoint cleanup&lt;/LI&gt;
&lt;LI&gt;Finalize the export or cancellation operation&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;Validate that:
&lt;UL&gt;
&lt;LI&gt;Operation transitions out of Running / CancelInProgress&lt;/LI&gt;
&lt;LI&gt;No active Import/Export operation remains&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H6&gt;&lt;U&gt;&lt;STRONG&gt;Key Takeaway&lt;/STRONG&gt;&lt;/U&gt;&lt;/H6&gt;
&lt;P&gt;Import/Export operations using Private Link &lt;STRONG&gt;depend on temporary service-managed infrastructure (private endpoints)&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;Any restriction (such as a Delete lock) that prevents cleanup of these resources can cause the operation to remain stuck at completion or cancellation phases.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H6&gt;&lt;U&gt;&lt;STRONG&gt;References&lt;/STRONG&gt;&lt;/U&gt;&lt;/H6&gt;
&lt;UL&gt;
&lt;LI&gt;Azure SQL Import/Export using Private Link (Microsoft Learn) &lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/database/database-import-export-private-link?view=azuresql#limitations" target="_blank" rel="noopener"&gt;Import or Export a Database Using Private Link - Azure SQL Database | Microsoft Learn&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Tue, 28 Apr 2026 06:07:55 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/azure-sql-database-bacpac-export-stuck-with-private-link-and/ba-p/4515271</guid>
      <dc:creator>hudajazmawi</dc:creator>
      <dc:date>2026-04-28T06:07:55Z</dc:date>
    </item>
    <item>
      <title>How to recover Azure SQL Managed Instance access when the admin SQL login is disabled</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/how-to-recover-azure-sql-managed-instance-access-when-the-admin/ba-p/4513905</link>
      <description>&lt;P&gt;&lt;STRONG&gt;Overview&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Some of you have probably ran into the issue of losing administrative access to Azure SQL Managed Instance because the SQL login(s) are disabled, or because the login is no longer a member of the &lt;STRONG&gt;sysadmin &lt;/STRONG&gt;fixed server role. Since we have received some cases on the matter, I'll be explaining one possible way to recover access in this scenario by using a Microsoft Entra administrator. Azure SQL Managed Instance supports both SQL logins and Microsoft Entra authentication, and the Microsoft Entra administrator for the managed instance can be set from the Azure portal, PowerShell, Azure CLI, or REST API.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Symptom&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Customers might see an error similar to the following when trying to connect with the SQL login:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Login failed for user 'sqlmiadmin'. Reason: The account is disabled. (Microsoft SQL Server, Error: 18470)&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Connection ID: 'XYZ'&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Scenario Details&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In the scenario discussed here, the SQL login(s) on the managed instance were either disabled, or their membership in the &lt;STRONG&gt;sysadmin &lt;/STRONG&gt;fixed server role was removed. As a result, there was no remaining SQL principal available with sufficient permissions to reverse the change directly. One possible recovery method is to configure, or reconfigure, a Microsoft Entra administrator for the managed instance and use that path to regain administrative access. Setting the Microsoft Entra administrator enables Microsoft Entra authentication for Azure SQL Managed Instance.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Root Cause&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The issue occurs because the required T-SQL statements can only be executed by principals that already have sufficient server-level permissions:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;ALTER LOGIN ... ENABLE requires ALTER ANY LOGIN. If the target login is a member of sysadmin, enabling or disabling that login also requires CONTROL SERVER.&lt;/LI&gt;
&lt;LI&gt;ALTER SERVER ROLE [sysadmin] ADD MEMBER ... can only be executed by a principal that is already a member of sysadmin or of that same fixed server role. CONTROL SERVER and ALTER ANY SERVER ROLE are not sufficient for adding members to a fixed server role.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Because of this, when no existing SQL principal can perform these actions or all logins gets disabled, an alternate administrative way is needed.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Resolution&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;One possible way to resolve the issue is to configure a Microsoft Entra administrator for the managed instance by following the steps in &lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/database/authentication-aad-configure?view=azuresql&amp;amp;tabs=azure-portal#azure-sql-database-and-azure-synapse-analytics" target="_blank" rel="noopener"&gt;Configure Microsoft Entra Authentication - Azure SQL Database &amp;amp; SQL Managed Instance &amp;amp; Azure Synapse Analytics | Microsoft Learn&lt;/A&gt;. In the Azure portal, go to the SQL managed instance resource, open &lt;STRONG&gt;Microsoft Entra ID&lt;/STRONG&gt; under &lt;STRONG&gt;Settings&lt;/STRONG&gt;, choose &lt;STRONG&gt;Set admin&lt;/STRONG&gt;, select the required user or group, and then select &lt;STRONG&gt;Save&lt;/STRONG&gt;. The same article also documents that you can remove the current Microsoft Entra admin and set it again if needed.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;After the Microsoft Entra administrator is configured, connect to the managed instance by using a supported Microsoft Entra authentication method, such as Microsoft Entra Password or Microsoft Entra MFA.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If the issue is that the SQL login is disabled, run the following T-SQL after connecting with a principal that has the required permissions:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;ALTER LOGIN [sqlmiadmin] ENABLE;
GO&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If the issue is that the login is no longer a member of &lt;STRONG&gt;sysadmin&lt;/STRONG&gt;, run the following T-SQL:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;ALTER SERVER ROLE [sysadmin] ADD MEMBER [sqlmiadmin];
GO&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Note&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;If the Microsoft Entra administrator was already configured and the Microsoft Entra login was also disabled. In such cases, you can remove the Microsoft Entra administrator from the Azure portal and set it again. This refreshes the Microsoft Entra administrator configuration for the managed instance and restores the Microsoft Entra authentication path.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Additional Resources&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/database/authentication-aad-configure?view=azuresql&amp;amp;tabs=azure-portal#azure-sql-database-and-azure-synapse-analytics" target="_blank" rel="noopener"&gt;Configure Microsoft Entra Authentication - Azure SQL Database &amp;amp; SQL Managed Instance &amp;amp; Azure Synapse Analytics | Microsoft Learn&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/database/authentication-microsoft-entra-connect-to-azure-sql?view=azuresql" target="_blank" rel="noopener"&gt;Connect with Microsoft Entra Authentication - Azure SQL Database &amp;amp; SQL Managed Instance &amp;amp; Azure Synapse Analytics | Microsoft Learn&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-login-transact-sql?view=sql-server-ver17" target="_blank" rel="noopener"&gt;ALTER LOGIN (Transact-SQL) - SQL Server | Microsoft Learn&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-server-role-transact-sql?view=sql-server-ver17" target="_blank" rel="noopener"&gt;ALTER SERVER ROLE (Transact-SQL) - SQL Server | Microsoft Learn&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Disclaimer&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Please note that products, features, and configuration options discussed in this article are subject to change. This article reflects the state of Azure SQL Managed Instance as of April 2026.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I hope you found this article helpful. Please feel free to share your feedback in the comments section.&lt;/P&gt;</description>
      <pubDate>Thu, 23 Apr 2026 12:05:50 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/how-to-recover-azure-sql-managed-instance-access-when-the-admin/ba-p/4513905</guid>
      <dc:creator>Abdullah_Qtaishat</dc:creator>
      <dc:date>2026-04-23T12:05:50Z</dc:date>
    </item>
    <item>
      <title>Azure SQL (LTR):
You Don’t Need to Copy LTR Backups Across Regions to Restore Them</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/azure-sql-ltr-you-don-t-need-to-copy-ltr-backups-across-regions/ba-p/4513774</link>
      <description>&lt;H3&gt;&lt;STRONG&gt;Summary&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;Customers sometimes attempt to &lt;STRONG&gt;copy Azure SQL Long-Term Retention (LTR) backups across regions&lt;/STRONG&gt; using &lt;STRONG&gt;Copy-AzSqlDatabaseLongTermRetentionBackup&lt;/STRONG&gt;, only to hit the error:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;LongTermRetentionMigrationRequestNotSupported&lt;/STRONG&gt;&lt;BR /&gt;&lt;EM&gt;LTR backup migration copy feature is not supported on subscription&lt;/EM&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This blog clarifies &lt;STRONG&gt;why this happens&lt;/STRONG&gt;, &lt;STRONG&gt;when LTR backup copy is actually supported&lt;/STRONG&gt;, and most importantly &lt;STRONG&gt;the correct and supported way to restore an LTR backup into a different region without copying it&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H2&gt;The Common Scenario&lt;/H2&gt;
&lt;P&gt;A customer has:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;An &lt;STRONG&gt;LTR backup stored in Region A&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;A need to &lt;STRONG&gt;restore the database into Region B&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;The assumption that the LTR backup must first be copied cross-region&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;They attempt:&lt;/P&gt;
&lt;LI-CODE lang="powershell"&gt;Copy-AzSqlDatabaseLongTermRetentionBackup&lt;/LI-CODE&gt;
&lt;P&gt;and immediately receive a platform validation error stating the feature isn’t supported on their subscription.&lt;/P&gt;
&lt;H2&gt;Why This Error Happens&lt;/H2&gt;
&lt;P&gt;The key misunderstanding is &lt;STRONG&gt;what the LTR backup copy API is actually for&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H3&gt;Copy-AzSqlDatabaseLongTermRetentionBackup is&amp;nbsp;&lt;STRONG&gt;NOT a general-purpose feature&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;This API is:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Backend-gated&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Allowlist-only&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Intended only for region decommissioning scenarios&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;In other words:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;It is &lt;STRONG&gt;not&lt;/STRONG&gt; supported for normal customer-driven migrations&lt;/LI&gt;
&lt;LI&gt;There is &lt;STRONG&gt;no portal toggle or feature registration&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Subscriptions are only allowlisted &lt;STRONG&gt;when Microsoft is retiring a region&lt;/STRONG&gt;, and LTR backups must be preserved elsewhere.&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Because of this, most subscriptions - will receive:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;LongTermRetentionMigrationRequestNotSupported&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H2&gt;The Correct &amp;amp; Supported Solution&lt;/H2&gt;
&lt;H3&gt;&lt;STRONG&gt;Good news:&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;You do NOT need to copy the LTR backup to another region to restore it there.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Azure SQL allows you to:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Restore an LTR backup directly to any Azure SQL logical server, in any region.&lt;/STRONG&gt;&lt;/P&gt;
&lt;H3&gt;Supported Approach: Restore LTR Backup Directly&lt;/H3&gt;
&lt;P&gt;Use &lt;STRONG&gt;Restore-AzSqlDatabase&lt;/STRONG&gt; with the -FromLongTermRetentionBackup switch.&lt;/P&gt;
&lt;H3&gt;Example (PowerShell)&lt;/H3&gt;
&lt;LI-CODE lang="powershell"&gt;Restore-AzSqlDatabase `
    -FromLongTermRetentionBackup `
    -ResourceId $ltrBackup.ResourceId `
    -ServerName $serverName `
    -ResourceGroupName $resourceGroup `
    -TargetDatabaseName "Test" `
    -ServiceObjectiveName P1&lt;/LI-CODE&gt;
&lt;UL&gt;
&lt;LI&gt;This works&amp;nbsp;&lt;STRONG&gt;across regions&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;No backend enablement required&lt;/LI&gt;
&lt;LI&gt;Fully supported and documented&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;How This Works (Important Concept)&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;LTR backups are stored in geo-redundant storage&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;The restore operation does &lt;STRONG&gt;not depend on the original region&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;The platform automatically handles data access and restores placement&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;So, while the &lt;STRONG&gt;backup physically originated in Region A&lt;/STRONG&gt;, you are free to restore it to &lt;STRONG&gt;Region B, C, or any supported Azure region&lt;/STRONG&gt; without copying it first.&lt;/P&gt;
&lt;H2&gt;When Is LTR Backup Copy Actually Used?&lt;/H2&gt;
&lt;P&gt;Only in this scenario:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Microsoft-initiated region decommissioning&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In that case:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;LTR backups must be relocated to remain available&lt;/LI&gt;
&lt;LI&gt;Subscriptions are temporarily &lt;STRONG&gt;allowlisted&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Copy-AzSqlDatabaseLongTermRetentionBackup&lt;/STRONG&gt; is enabled at the backend&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Outside of this scenario, the API is &lt;STRONG&gt;intentionally restricted&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H2&gt;Key Takeaways&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;You can restore an LTR backup to any region directly&lt;/LI&gt;
&lt;LI&gt;You do not need (and usually cannot use) LTR backup copy&lt;/LI&gt;
&lt;LI&gt;Backup copy is gated and reserved for region retirement scenarios&lt;/LI&gt;
&lt;LI&gt;Use &lt;STRONG&gt;Restore-AzSqlDatabase -FromLongTermRetentionBackup&lt;/STRONG&gt; instead&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Final Recommendation for Customers&lt;/H2&gt;
&lt;P&gt;If customers encounter this error:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Reassure them this is &lt;STRONG&gt;not a misconfiguration or permission issue&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Explain that &lt;STRONG&gt;LTR restore is the correct solution&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Avoid escalation for feature enablement unless a &lt;STRONG&gt;region retirement&lt;/STRONG&gt; is involved&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Wed, 22 Apr 2026 18:31:59 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/azure-sql-ltr-you-don-t-need-to-copy-ltr-backups-across-regions/ba-p/4513774</guid>
      <dc:creator>Mohamed_Baioumy_MSFT</dc:creator>
      <dc:date>2026-04-22T18:31:59Z</dc:date>
    </item>
    <item>
      <title>Azure Data Sync: Fixing “Cannot find the user ‘DataSync_executor’” When Creating a New Sync Group</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/azure-data-sync-fixing-cannot-find-the-user-datasync-executor/ba-p/4513757</link>
      <description>&lt;H2&gt;Summary&lt;/H2&gt;
&lt;P&gt;When creating a &lt;STRONG&gt;new Azure SQL Data Sync group&lt;/STRONG&gt;, customers may encounter the following error during setup—even when no active sync groups exist:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;“Failed to perform data sync operation: Cannot find the user 'DataSync_executor', because it does not exist or you do not have permission.”&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This failure typically occurs during&amp;nbsp;&lt;STRONG&gt;certificate and symmetric key creation&lt;/STRONG&gt; as Azure attempts to grant permissions to the DataSync_executor role. In this post, we’ll walk through:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The &lt;STRONG&gt;common scenario&lt;/STRONG&gt; where this issue appears&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Why cleanup scripts alone may not fix it&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;A &lt;STRONG&gt;supported, reliable resolution approach&lt;/STRONG&gt; to restore Data Sync successfully&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;The Problem Scenario&lt;/H2&gt;
&lt;P&gt;A customer attempts to create a &lt;STRONG&gt;brand-new Azure SQL Data Sync group&lt;/STRONG&gt; (hub + members), but the operation fails with an error similar to:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Cannot find the user 'DataSync_executor', because it does not exist or you do not have permission. Creating certificate Creating symmetric key Granting permission to [DataSync_executor] on certificate&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Key observations from affected cases:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;No active sync group exists&lt;/LI&gt;
&lt;LI&gt;Cleanup scripts (including &lt;STRONG&gt;Data Sync complete cleanup.sql&lt;/STRONG&gt;) were already executed&lt;/LI&gt;
&lt;LI&gt;The failure persists even after retrying the setup&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Why This Happens&lt;/H2&gt;
&lt;P&gt;Azure SQL Data Sync depends on &lt;STRONG&gt;system-managed database roles&lt;/STRONG&gt; that must be created and configured &lt;STRONG&gt;only by the Azure Data Sync service itself&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;If these roles (or related permissions) are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Missing&lt;/LI&gt;
&lt;LI&gt;Partially deleted&lt;/LI&gt;
&lt;LI&gt;Left in an inconsistent state&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;then Data Sync may fail while attempting to create certificates or grant required permissions.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;Important:&lt;/STRONG&gt;&lt;BR /&gt;Manually creating or partially restoring these roles is &lt;STRONG&gt;not supported&lt;/STRONG&gt; and often leads to repeated failures.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H2&gt;How to Detect the Issue&lt;/H2&gt;
&lt;P&gt;Before troubleshooting further, confirm whether the required Data Sync roles are missing.&lt;/P&gt;
&lt;H3&gt;1. Run the Data Sync Health Checker&lt;/H3&gt;
&lt;P&gt;Ask the customer to run&amp;nbsp;&lt;A class="lia-external-url" href="https://github.com/Microsoft/AzureSQLDataSyncHealthChecker" target="_blank"&gt;&lt;STRONG&gt;Data Sync Health Checker&lt;/STRONG&gt;&lt;/A&gt;, then review SyncDB_Log.&lt;/P&gt;
&lt;P&gt;Common warnings include:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;DataSync_reader IS MISSING&lt;/LI&gt;
&lt;LI&gt;DataSync_executor IS MISSING&lt;/LI&gt;
&lt;LI&gt;Missing EXECUTE/SELECT permissions on dss and TaskHosting schemas&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This confirms the root cause is&amp;nbsp;&lt;STRONG&gt;role and permission inconsistency&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H2&gt;Supported and Effective Resolution&lt;/H2&gt;
&lt;H3&gt;Step 1: Verify Roles Are Missing&lt;/H3&gt;
&lt;P&gt;Run the following query on &lt;STRONG&gt;each affected database&lt;/STRONG&gt; (hub and members):&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT name
FROM sys.database_principals
WHERE name IN ('DataSync_executor', 'DataSync_reader');&lt;/LI-CODE&gt;
&lt;P&gt;If&amp;nbsp;&lt;STRONG&gt;no rows are returned&lt;/STRONG&gt;, the roles are missing and must be recovered by Azure Data Sync itself - not manually.&lt;/P&gt;
&lt;H3&gt;Step 2: Fully Clean Up Leftover Data Sync Objects&lt;/H3&gt;
&lt;P&gt;Do this&amp;nbsp;&lt;STRONG&gt;only if the database is not actively syncing&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;-- Remove roles if partially present
DROP ROLE IF EXISTS DataSync_executor;
DROP ROLE IF EXISTS DataSync_reader;

-- Drop DataSync schema
IF EXISTS (SELECT 1 FROM sys.schemas WHERE name = 'DataSync')
BEGIN
    DROP SCHEMA DataSync;
END&lt;/LI-CODE&gt;
&lt;P&gt;This ensures there are&amp;nbsp;&lt;STRONG&gt;no partial or orphaned Data Sync objects&lt;/STRONG&gt; left behind that could interfere with setup.&lt;/P&gt;
&lt;H3&gt;Step 3: Recreate the Sync Group (Critical Step)&lt;/H3&gt;
&lt;P&gt;Do&amp;nbsp;&lt;STRONG&gt;not&lt;/STRONG&gt; manually recreate roles or permissions&lt;BR /&gt;Instead:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Delete the existing (failed) Sync Group from the &lt;STRONG&gt;Azure Portal&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Recreate the Sync Group from scratch&lt;/LI&gt;
&lt;LI&gt;Re-add the hub and member databases&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;During this process, Azure will automatically:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Recreate DataSync_executor and DataSync_reader&lt;/LI&gt;
&lt;LI&gt;Assign all required permissions&lt;/LI&gt;
&lt;LI&gt;Deploy the correct schemas, certificates, and procedures&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Key Takeaways&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;DataSync_executor and DataSync_reader are &lt;STRONG&gt;service-managed roles&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Cleanup scripts alone may not fully reset a broken state&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Manual role creation is not supported&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Deleting and recreating the Sync Group is the &lt;STRONG&gt;only reliable recovery method&lt;/STRONG&gt; once roles are missing&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Final Recommendation&lt;/H2&gt;
&lt;P&gt;If you encounter &lt;STRONG&gt;Data Sync setup failures referencing DataSync_executor&lt;/STRONG&gt;, always:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Validate role existence&lt;/LI&gt;
&lt;LI&gt;Fully clean up broken artifacts&lt;/LI&gt;
&lt;LI&gt;Let &lt;STRONG&gt;Azure Data Sync&lt;/STRONG&gt; recreate everything by rebuilding the Sync Group&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;This approach consistently resolves the issue and restores a healthy Data Sync deployment.&lt;/P&gt;</description>
      <pubDate>Wed, 22 Apr 2026 17:17:34 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/azure-data-sync-fixing-cannot-find-the-user-datasync-executor/ba-p/4513757</guid>
      <dc:creator>Mohamed_Baioumy_MSFT</dc:creator>
      <dc:date>2026-04-22T17:17:34Z</dc:date>
    </item>
    <item>
      <title>Data Migration - From SQL MI to SQL DB migration</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/data-migration-from-sql-mi-to-sql-db-migration/ba-p/4461627</link>
      <description>&lt;H1&gt;Overview&lt;/H1&gt;
&lt;P&gt;In this post, I’ll show you how to perform a data migration from Azure SQL Managed Instance (SQL MI) to Azure SQL Database (SQL DB) using a combination of schema + security migration steps and Azure Data Factory (ADF) for moving the data. In an earlier post (&lt;A class="lia-internal-link lia-internal-url lia-internal-url-content-type-blog" href="https://techcommunity.microsoft.com/blog/azuredbsupport/data-migration---azure-sql-mi-and-azure-sql-db/4461457" target="_blank" rel="noopener" data-lia-auto-title="Data Migration - Azure SQL MI and Azure SQL DB | Microsoft Community Hub" data-lia-auto-title-active="0"&gt;Data Migration - Azure SQL MI and Azure SQL DB | Microsoft Community Hub&lt;/A&gt;), I briefly covered several approaches for moving data from SQL MI to SQL DB. This article focuses on an approach that works well when you want a repeatable data-movement pipeline (ADF) but still need to migrate database objects and users as part of a complete cutover. Using ADF is a good option when you need a repeatable pipeline or when the source data volume is large. This article walks one of the methods you can use, particularly if source data size is large. This post will walk you through the key configuration steps to copy data from SQL MI to SQL DB using ADF.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;Note&lt;/STRONG&gt;: If you want to migrate in the opposite direction (Azure SQL Database → SQL Managed Instance), you can follow the same general flow in this article—just swap which platform is the source and which is the destination and adjust any feature-compatibility work accordingly.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The steps below assume that you are migrating data over a private endpoint so that all traffic remains on a secure, private network path. In this configuration, you deploy a Windows VM to host a &lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/data-factory/choose-the-right-integration-runtime-configuration#self-hosted-integration-runtime" target="_blank" rel="noopener"&gt;Self‑Hosted Integration Runtime&lt;/A&gt; (SHIR). If your requirements permit data movement over the public network, you can instead use the Azure Integration Runtime (Azure IR), which removes the need for a Windows VM and SHIR. In that case, Azure IR handles the data movement, and traffic flows over the public network rather than through a private endpoint.&lt;/P&gt;
&lt;H2&gt;High-level steps&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;Assess compatibility and feature differences (SQL MI vs SQL DB)&lt;/LI&gt;
&lt;LI&gt;Migrate schema and database objects (tables, views, procs, functions, etc.)&lt;/LI&gt;
&lt;LI&gt;Migrate users and permissions (and map logins to users where applicable)&lt;/LI&gt;
&lt;LI&gt;Deploy Azure Data Factory (ADF)&lt;/LI&gt;
&lt;LI&gt;(If using private endpoints) Provision a Windows VM to host SHIR and register it in ADF&lt;/LI&gt;
&lt;LI&gt;Create linked services (connections) for SQL MI and SQL DB&lt;/LI&gt;
&lt;LI&gt;Run the data copy using the Copy Data tool (or a pipeline), validate, and cut over&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;Pre-migration assessment (SQL MI → SQL DB)&lt;/H1&gt;
&lt;P&gt;There is no automated assessment tool available to evaluate readiness for migrating between Azure SQL Managed Instance and Azure SQL Database. As a result, pre‑migration assessment is a manual exercise. Before migrating, you should validate high‑level compatibility, including supported features, removal of instance‑level or cross‑database dependencies, security model alignment, target service tier sizing, and application connectivity behavior. Differences in platform capabilities and architecture should be reviewed early to avoid migration or post‑migration issues.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here is check list to consider:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;☐ Feature compatibility reviewed (no unsupported MI features in use)
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/database/features-comparison?view=azuresql" target="_blank" rel="noopener"&gt;Compare SQL Database Engine Features - Azure SQL Database &amp;amp; Azure SQL Managed Instance | Microsoft Learn&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/database/connect-query-ssms?view=azuresql" target="_blank" rel="noopener"&gt;SSMS: Connect and query data - Azure SQL Database &amp;amp; Azure SQL Managed Instance | Microsoft Learn&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;☐ No instance‑level or cross‑database dependencies required&lt;/LI&gt;
&lt;LI&gt;☐ Security model validated (database‑scoped users and authentication)&lt;/LI&gt;
&lt;LI&gt;☐ Target SQL Database service tier identified and sized&lt;/LI&gt;
&lt;LI&gt;☐ Application connectivity updated (connection strings, retries, HA behavior)&lt;/LI&gt;
&lt;LI&gt;☐ Proof‑of‑concept testing completed with a representative database&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;Migrate schema and database objects&lt;/H1&gt;
&lt;P&gt;ADF is primarily a data movement service, so migrate your (*1) schema and programmable objects first. Common options include deploying a DACPAC (SqlPackage) to Azure SQL Database, using SQL Server Data Tools (SSDT) to publish a database project, or generating scripts from SSMS (tables, views, stored procedures, functions, synonyms, sequences, user-defined types, etc.). Ensure the target schema matches the source (data types, collations, constraints) before you start the bulk data copy.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;(*1) In the Copy Data tool step (described later), ADF can auto-create the table schemas (and views) based on the source tables. So, you can skip migrating the schema upfront; however, programmable objects (stored procedures, function, etc.) and other non-schema objects have to be migrated.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;OL&gt;
&lt;LI&gt;Create the target Azure SQL Database (and choose the correct server, tier, and size).&lt;/LI&gt;
&lt;LI&gt;Deploy the schema and objects to SQL DB (DACPAC/SSDT/scripts).&lt;/LI&gt;
&lt;LI&gt;Create supporting objects needed for the load (schemas, filegroups aren’t applicable in SQL DB, but schemas and tables are).&lt;/LI&gt;
&lt;LI&gt;Decide when to create indexes and foreign keys: for very large loads, creating them after the data copy can significantly speed up ingestion.&lt;/LI&gt;
&lt;/OL&gt;
&lt;H1&gt;Deploy ADF&lt;/H1&gt;
&lt;P&gt;Follow the steps in &lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/data-factory/quickstart-create-data-factory" target="_blank" rel="noopener"&gt;Create an Azure Data Factory - Azure Data Factory | Microsoft Learn&lt;/A&gt; to deploy ADF. After deployment, open Azure Data Factory Studio—we’ll use it to configure the integration runtime, linked services, and the copy activity. Following ADF deployment, launch the Azure Data Factory Studio. We will come back to what needs to be configured in ADF Studio&lt;/P&gt;
&lt;H1&gt;Provision Windows VM – used to host SHIR&lt;/H1&gt;
&lt;P&gt;This Azure VM hosts the &lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/data-factory/choose-the-right-integration-runtime-configuration#self-hosted-integration-runtime" target="_blank" rel="noopener"&gt;Self-hosted Integration Runtime (SHIR)&lt;/A&gt;, which ADF uses to connect to your SQL MI and SQL DB over private networking and to run the copy operation.&lt;/P&gt;
&lt;H1&gt;Configure SHIR in Azure Data Factory and install SHIR on Azure VM&lt;/H1&gt;
&lt;P&gt;On the page for your data factory, select &lt;STRONG&gt;Launch Studio&lt;/STRONG&gt; to open &lt;STRONG&gt;Azure Data Factory Studio&lt;/STRONG&gt;. The steps below assume you are working from the Azure VM that will host SHIR. If the VM can’t download the SHIR installer (for example, it has no outbound internet access), download the installer from a machine that has internet access and then copy it to the VM.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;Select (1) &lt;STRONG&gt;Manage&lt;/STRONG&gt;, and then (2) &lt;STRONG&gt;Integration runtimes&lt;/STRONG&gt; to display the integration runtimes.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;Select &lt;STRONG&gt;New &lt;/STRONG&gt;which will display the &lt;STRONG&gt;Integration runtime&amp;nbsp;setup&lt;/STRONG&gt; page at right.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Select &lt;STRONG&gt;Azure, Self-Hosted&lt;/STRONG&gt;, and then select &lt;STRONG&gt;Continue&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Select &lt;STRONG&gt;Self-Hosted&lt;/STRONG&gt;, and then select &lt;STRONG&gt;Continue&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Enter a name for the integration runtime, and then select &lt;STRONG&gt;Create&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;For this example, use &lt;STRONG&gt;Manual setup&lt;/STRONG&gt; (Option 2) rather than express setup. Download the integration runtime installer from the provided link.&lt;/LI&gt;
&lt;/OL&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;After downloading the SHIR installer, close the page for now. Back on the &lt;STRONG&gt;Integration runtimes&lt;/STRONG&gt; page (in ADF studio), you’ll see the new runtime listed with a status of 'Unavailable'. It will change to 'Running' after you install and register SHIR on the VM.&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;Run the SHIR installer (the .msi file) and complete the installation wizard. At the end of the wizard, you’ll be prompted to register the integration runtime.&lt;/P&gt;
&lt;P&gt;To get the authentication key, return to ADF Studio, select your integration runtime on the &lt;STRONG&gt;Integration runtimes&lt;/STRONG&gt; page to open &lt;STRONG&gt;Edit integration runtime&lt;/STRONG&gt;, and then copy the key. Paste the key into the SHIR registration dialog on the VM. Select &lt;STRONG&gt;Register &lt;/STRONG&gt;to complete registration.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;After registration completes, select &lt;STRONG&gt;Finish &lt;/STRONG&gt;to close the wizard. You can leave &lt;STRONG&gt;Enable remote access from intranet&lt;/STRONG&gt; unchecked unless you plan to add additional SHIR nodes for high availability and scalability. You can change this setting later if needed.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;If the registration succeeds, you will see the integration runtimes is at running status.&lt;/P&gt;
&lt;img /&gt;
&lt;H1&gt;Configure Linked Service (connections to source and target)&lt;/H1&gt;
&lt;P&gt;In this step, you configure connections to the source (SQL MI) and the target (Azure SQL DB).&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Important: ADF copy activities migrate data. You must create the target database ahead of time.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P class=""&gt;In ADF Studio, go to &lt;STRONG&gt;Manage&lt;/STRONG&gt; &amp;gt; &lt;STRONG&gt;Linked services&lt;/STRONG&gt;. This will display the&amp;nbsp;&lt;STRONG&gt;New linked service&lt;/STRONG&gt; pane.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;Note: If you already have linked services created for both SQL MI and SQL DB, you can reuse them—when configuring the Copy Data tool or a pipeline, simply select the existing linked service for the source and the existing linked service for the destination.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Search for 'sql' to display related connectors. in Data stores. Select the connector for SQL MI, and then select Continue.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;Enter required properties to connect to SQL MI.&lt;/P&gt;
&lt;P&gt;For &lt;STRONG&gt;Connect via integration runtime&lt;/STRONG&gt;, select the self-hosted integration runtime you created earlier.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;Set the remaining properties as appropriate for your environment (server name, database name, authentication, etc.). For other properties, set/enter appropriate values to connect to your server.&lt;/P&gt;
&lt;P&gt;Example settings used in this demo (key properties only):&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Endpoint type: Private endpoint&lt;/LI&gt;
&lt;LI&gt;Authentication type: SQL authentication (demo only—use your preferred/approved auth method)&lt;/LI&gt;
&lt;LI&gt;Trust server certificate: Selected&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Next, create a linked service for the target server (Azure SQL Database). Follow the same general steps you used for SQL MI, selecting the appropriate connector and the same SHIR (if you are using private endpoints). You can follow the same steps as done with SQL MI&lt;/P&gt;
&lt;P&gt;When finished, you should see two linked services configured—one for SQL MI and one for SQL DB.&lt;/P&gt;
&lt;img /&gt;
&lt;H1&gt;Configure Ingestion and run data migration&lt;/H1&gt;
&lt;P&gt;Now we are ready to perform the data migration. Select [Home] at the ADF Studio and select [Ingest]. This will display the Copy Data tool page.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;Important&lt;/STRONG&gt;: Before you start, make sure the target database exists in Azure SQL Database and that you have permissions to create/insert data into the target tables.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;For larger migrations, consider copying in batches (for example, by date/key range) and using parallelism where appropriate to improve throughput while staying within SQL DB resource limits. Plan time for validation (row counts/checksums or targeted queries) and decide how you will handle ongoing changes during cutover (for example, a final delta load or an application downtime window).&lt;/P&gt;
&lt;img /&gt;
&lt;H3&gt;The Copy Data tool page&lt;/H3&gt;
&lt;P&gt;Select &lt;STRONG&gt;Built-in copy task &amp;gt;&amp;nbsp;&lt;/STRONG&gt;&lt;STRONG&gt;Run once now&lt;/STRONG&gt;, and &lt;STRONG&gt;Continue&lt;/STRONG&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Select Source type and connection.&amp;nbsp; Select table(s) to migrate.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;Select &lt;STRONG&gt;Next &lt;/STRONG&gt;at the [Apply filter] page&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;Select the destination&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;Select &lt;STRONG&gt;Next &lt;/STRONG&gt;to get to Column mapping page. Unless you want to&amp;nbsp;&lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/data-factory/copy-activity-schema-and-type-mapping" target="_blank" rel="noopener"&gt;specify explicit mapping&lt;/A&gt; to customize column/field mapping from source to destination, select &lt;STRONG&gt;Next&lt;/STRONG&gt; to accept default settings.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;At the &lt;STRONG&gt;Copy Data tool&lt;/STRONG&gt; page, leave all with default settings and continue &lt;STRONG&gt;Next&lt;/STRONG&gt;.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;On the &lt;STRONG&gt;Summary&lt;/STRONG&gt; page, select &lt;STRONG&gt;Next &lt;/STRONG&gt;to start data migration.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;After selecting &lt;STRONG&gt;Next&lt;/STRONG&gt;, the migration starts.&amp;nbsp; You can select &lt;STRONG&gt;Finish &lt;/STRONG&gt;to close this page and continue monitor the migration progress from the Monitor blade.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;Checking migration status&lt;/H1&gt;
&lt;P&gt;You can select &lt;STRONG&gt;Finish&lt;/STRONG&gt; to close the page and go to&amp;nbsp;&lt;STRONG&gt;Monitor &lt;/STRONG&gt;to monitor the migration progress.&lt;/P&gt;
&lt;img /&gt;
&lt;H1&gt;Validation and cutover&lt;/H1&gt;
&lt;P&gt;After schema, security, and data are migrated, validate the target before switching applications over to SQL DB. Validation typically includes row counts, checksum sampling, and running key application queries and reports against the new database. For cutover, plan how you will handle changes occurring on SQL MI while the bulk copy is running (for example, schedule downtime, or run a final delta load if your design supports it).&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Validate schema: object counts, constraints, and (if used) post-deployment scripts.&lt;/LI&gt;
&lt;LI&gt;Validate security: users/groups exist, role memberships are correct, and the app can connect with least privilege.&lt;/LI&gt;
&lt;LI&gt;Validate data: row counts per table, spot-check aggregates, and targeted checksum comparisons where feasible.&lt;/LI&gt;
&lt;LI&gt;Cut over: update connection strings/DNS, monitor workload in SQL DB, and keep a rollback plan.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Notes and Observations&lt;/H2&gt;
&lt;H3&gt;Migrating database objects&lt;/H3&gt;
&lt;P&gt;Although this article recommends migrating schemas and database objects before copying data, this demo relies on Azure Data Factory’s automatic schema generation for simplicity. This is useful for testing or learning ADF workflows, but it is not suitable for production migrations.&lt;/P&gt;
&lt;P&gt;The &lt;A class="lia-external-url" href="https://github.com/Microsoft/sql-server-samples/releases/tag/wide-world-importers-v1.0" target="_blank" rel="noopener"&gt;Wide World Importers&lt;/A&gt; sample database, that was used for the source database, includes a memory‑optimized table, but ADF generated a standard table instead. This illustrates a key limitation: ADF creates tables using basic metadata (columns, data types, and keys) and does not generate full, feature‑equivalent schemas.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Best practice&lt;/STRONG&gt;: Use tools such as SSMS, SSDT, DACPAC, or BACPAC to prepare complete schemas and objects in the target database and use ADF strictly for data movement.&lt;/P&gt;
&lt;H3&gt;Online migration&lt;/H3&gt;
&lt;P&gt;Online migration keeps the source database available while data is copied to the target using a repeatable pipeline such as Azure Data Factory. Schema and security are prepared in advance, and the bulk data copy runs without requiring an extended outage.&lt;/P&gt;
&lt;P&gt;Changes made to the source during the copy aren’t automatically synchronized, so a planned cutover—such as a short downtime window or final validation step—is still required to ensure data consistency before switching applications to the target.&lt;/P&gt;
&lt;H1&gt;Summary&lt;/H1&gt;
&lt;P&gt;Migrating from SQL MI to Azure SQL Database is more than a single copy operation. A successful full migration typically includes (1) assessing feature compatibility, (2) deploying schema and objects to the target, (3) recreating users/roles/permissions, and (4) using ADF to move the data in a repeatable, monitorable way—optionally through private networking with SHIR. After the copy completes, validate schema, security, and data, then execute a planned cutover to move applications to SQL DB.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Assess and remediate MI→SQL DB compatibility gaps.&lt;/LI&gt;
&lt;LI&gt;Migrate schema + programmable objects (DACPAC/SSDT/scripts) before loading data.&lt;/LI&gt;
&lt;LI&gt;Migrate security: users, roles, role memberships, and permissions (prefer Entra ID where possible).&lt;/LI&gt;
&lt;LI&gt;Configure ADF (and SHIR if using private endpoints), then run Copy Data/pipelines for the data load.&lt;/LI&gt;
&lt;LI&gt;Validate results and cut over with a rollback plan.&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Wed, 22 Apr 2026 05:25:10 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/data-migration-from-sql-mi-to-sql-db-migration/ba-p/4461627</guid>
      <dc:creator>akiohose</dc:creator>
      <dc:date>2026-04-22T05:25:10Z</dc:date>
    </item>
    <item>
      <title>Fix failover group creation errors with TDE CMK on Azure SQL Managed Instance</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/fix-failover-group-creation-errors-with-tde-cmk-on-azure-sql/ba-p/4513322</link>
      <description>&lt;P&gt;&lt;STRONG&gt;Overview&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;We have received several support cases where customers encounter the error shown below when attempting to create a failover group for Azure SQL Managed Instance. In this article, we explore one of the possible causes of this error.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Creating instance failover group failed.&lt;/P&gt;
&lt;P&gt;An unexpected error occured while processing the request. Tracking ID: 'XYZ'&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Prerequisites Review&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;This article focuses on an additional configuration requirement beyond what is documented in&lt;BR /&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/managed-instance/failover-group-configure-sql-mi?view=azuresql&amp;amp;tabs=azure-portal%2Cazure-portal-modify%2Cazure-powershell-manage#configuration-requirements" target="_blank" rel="noopener"&gt;Configure a failover group - Azure SQL Managed Instance | Microsoft Learn&lt;/A&gt;:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The secondary managed instance must be empty, without any user databases.&lt;/LI&gt;
&lt;LI&gt;The configuration of your primary and secondary instance should be the same to ensure the secondary instance can sustainably process changes replicated from the primary instance, including during periods of peak activity. This includes the compute size, storage size, and service tier.&lt;/LI&gt;
&lt;LI&gt;The IP&amp;nbsp;&lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/managed-instance/failover-group-configure-sql-mi?view=azuresql&amp;amp;tabs=azure-portal%2Cazure-portal-modify%2Cazure-powershell-manage#create-virtual-network" target="_blank" rel="noopener"&gt;address range&lt;/A&gt;&amp;nbsp;for the virtual network of the primary instance must not overlap with the address range of the virtual network for the secondary managed instance, or any other virtual network peered with either the primary or secondary virtual network.&lt;/LI&gt;
&lt;LI&gt;Both instances must be in the same DNS zone. When you create your secondary managed instance, you must specify the primary instance's DNS zone ID. If you don't, the zone ID is generated as a random string when the first instance is created in each virtual network and the same ID is assigned to all other instances in the same subnet. Once assigned, the DNS zone can't be modified.&lt;/LI&gt;
&lt;LI&gt;Network Security Groups (NSG) rules for the subnets of both instances must have open inbound and outbound TCP connections for port 5022 and port range 11000-11999 to facilitate communication between the two instances.&lt;/LI&gt;
&lt;LI&gt;Managed instances should be deployed to&amp;nbsp;&lt;A href="https://learn.microsoft.com/en-us/azure/reliability/cross-region-replication-azure" target="_blank" rel="noopener"&gt;paired regions&lt;/A&gt;&amp;nbsp;for performance reasons. Managed instances that reside in geo-paired regions benefit from a significantly higher geo-replication speed compared to unpaired regions.&lt;/LI&gt;
&lt;LI&gt;Both instances must use the same&amp;nbsp;&lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/managed-instance/update-policy?view=azuresql" target="_blank" rel="noopener"&gt;update policy&lt;/A&gt;.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In the scenario discussed here, all of the above requirements were fully satisfied.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Scenario Details&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The primary SQL Managed Instance was configured to use customer‑managed keys (CMK) for Transparent Data Encryption (TDE), with automatic key rotation enabled.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The secondary SQL Managed Instance was configured to use service‑managed keys (SMK) or it can be configured with a different CMK than the one used by the primary instance for database encryption.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Root Cause&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The issue occurs because all servers participating in geo‑replication must share the same key material as the encryption protector of the primary server. This requirement is documented in&lt;BR /&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/database/transparent-data-encryption-byok-overview?view=azuresql&amp;amp;tabs=azurekeyvault%2Cazurekeyvaultrequirements%2Cazurekeyvaultrecommendations#geo-dr-and-customer-managed-tde" target="_blank" rel="noopener"&gt;Customer-managed transparent data encryption (TDE) - Azure SQL Database &amp;amp; Azure SQL Managed Instance &amp;amp; Azure Synapse Analytics | Microsoft Learn&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In this scenario, the mismatch between CMK on the primary instance and SMK on the secondary instance caused the failover group creation to fail.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Resolution&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;If there is a requirement &lt;STRONG&gt;not&lt;/STRONG&gt; to encrypt the secondary managed instance databases using the same key as the primary for example, to continue using SMK you can still satisfy the failover group requirement without changing the active encryption protector on the secondary instance.&lt;/P&gt;
&lt;P&gt;To achieve this:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Add the &lt;STRONG&gt;primary instance’s TDE key&lt;/STRONG&gt; to the secondary managed instance.&lt;/LI&gt;
&lt;LI&gt;Ensure that the option &lt;STRONG&gt;“Make this key the default TDE protector”&lt;/STRONG&gt; is &lt;STRONG&gt;disabled&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This allows the key to be used solely for failover group operations while keeping SMK or different CMK as the active TDE protector on the secondary instance after failover group creation.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;After fixing the issue, failover group was successfully created.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Additional Resources&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/managed-instance/failover-group-configure-sql-mi?view=azuresql&amp;amp;tabs=azure-portal%2Cazure-portal-modify%2Cazure-powershell-manage#configuration-requirements" target="_blank" rel="noopener"&gt;Configure a failover group - Azure SQL Managed Instance | Microsoft Learn&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/database/transparent-data-encryption-byok-overview?view=azuresql&amp;amp;tabs=azurekeyvault%2Cazurekeyvaultrequirements%2Cazurekeyvaultrecommendations#geo-dr-and-customer-managed-tde" target="_blank" rel="noopener"&gt;Customer-managed transparent data encryption (TDE) - Azure SQL Database &amp;amp; Azure SQL Managed Instance &amp;amp; Azure Synapse Analytics | Microsoft Learn&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Disclaimer&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Please note that products, features, and configuration options discussed in this article are subject to change. This article reflects the state of Azure SQL Managed Instance as of April 2026.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;We hope you found this article helpful. Please feel free to share your feedback in the comments section.&lt;/P&gt;</description>
      <pubDate>Tue, 21 Apr 2026 11:06:46 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/fix-failover-group-creation-errors-with-tde-cmk-on-azure-sql/ba-p/4513322</guid>
      <dc:creator>Abdullah_Qtaishat</dc:creator>
      <dc:date>2026-04-21T11:06:46Z</dc:date>
    </item>
    <item>
      <title>How to take copy only backups with SQL Managed Instance.</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/how-to-take-copy-only-backups-with-sql-managed-instance/ba-p/4512541</link>
      <description>&lt;P&gt;In Azure SQL Managed Instance, copy-only backups cannot be created for databases encrypted with service-managed Transparent Data Encryption (The default for all newly provisioned SQL MI). Service-managed TDE relies on an internal encryption key that cannot be exported, which means the backup cannot be restored outside that environment. You will need to change your SQL MI TDE service key for this process (I will explain how to do this in Step 4 below).&lt;/P&gt;
&lt;P&gt;In this article, I will explain how to prepare your Azure SQL Managed Instance (SQL MI) to take copy-only backups to Azure Blob Storage by using Managed Identity together with customer-managed encryption keys.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;These steps ensure that SQL MI can encrypt the backup by using your own key and securely write it to your storage account without relying on shared keys or SAS tokens.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 1: Create or Identify a Backup Encryption Key in Azure Key Vault&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;First, ensure that you have a Key Vault containing a key that will be used to encrypt the backup. It is essential to have elevated privileges over this key vault, and it's recommended to use a dedicated key for the backup encryption.&lt;/P&gt;
&lt;P&gt;Note the Key Identifier:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;https://contoso.vault.azure.net/keys/contosokey/01234567890123456789012345678901&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;as it will be required later when adding the key to SQL MI. This key will be used by SQL MI to encrypt the backup before it is written to Azure Blob Storage.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 2: Grant Key Vault Permissions to the SQL MI Managed Identity&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;SQL Managed Instance uses a system-assigned managed identity. This allows SQL MI to use the key for encryption and decryption operations during backup and restore. This identity must be granted escalated privileges to use the encryption key stored in Key Vault.&lt;/P&gt;
&lt;P&gt;In the Key Vault:&lt;/P&gt;
&lt;P&gt;1) Navigate to Access control (IAM) or Access policies (depending on whether RBAC or Access Policies are enabled).&lt;/P&gt;
&lt;P&gt;2) Choose the SQL MI managed identity.&lt;/P&gt;
&lt;P&gt;3) Assign it this role:&amp;nbsp; "Key Vault Crypto Service Encryption User".&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Note: If you're using Access Policies mode, then the required key permissions are Get, Wrap Key, Unwrap Key.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 3: Grant Storage Permissions to the SQL MI Managed Identity&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Next, SQL MI must be authorized to write backup files to the target storage account. This role assignment allows SQL MI to create, write, and manage blobs within the specified container. No storage account keys or SAS tokens are required when using Managed Identity.&lt;/P&gt;
&lt;P&gt;In the storage account that hosts your backup container:&lt;/P&gt;
&lt;P&gt;1) Go to Access control (IAM).&lt;/P&gt;
&lt;P&gt;2) Choose the SQL MI managed identity.&lt;/P&gt;
&lt;P&gt;3) Assign it this role: "Storage Blob Data Contributor"&lt;/P&gt;
&lt;P&gt;Note: Verify that connectivity from the storage account to SQL MI is established successfully. The storage account must allow the SQL MI subnet to connect to it. Use this script to test connectivity to the storage account from SQL MI: &lt;A href="https://github.com/Azure/sqlmi/blob/main/how-to/how-to-test-tcp-connection-from-mi/TestTCPNetworkConnection.sql" target="_blank" rel="noopener"&gt;how-to-test-tcp-connection-from-mi&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 4: Add the Encryption Key to SQL Managed Instance&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;After Key Vault access has been configured, the encryption key must be registered within SQL MI. You can add the key in two ways:&lt;/P&gt;
&lt;P&gt;A) From Azure portal:&lt;/P&gt;
&lt;P&gt;Navigate to the relevant SQL Managed Instance, then select the &lt;EM&gt;Security&lt;/EM&gt; option from the left-hand menu. Under &lt;EM&gt;Security&lt;/EM&gt;, open &lt;EM&gt;Transparent Data Encryption&lt;/EM&gt;. From there, you will be able to select the appropriate key from the available drop-down list. Click save once your choice is complete.&lt;/P&gt;
&lt;P&gt;B) From Azure Cloud Shell/PowerShell:&lt;/P&gt;
&lt;P&gt;First, add the key first with this command:&lt;/P&gt;
&lt;LI-CODE lang="powershell"&gt;Add-AzSqlInstanceKeyVaultKey -ResourceGroupName 'ContosoResourceGroup' -InstanceName 'ContosoManagedInstanceName' -KeyId 'https://contoso.vault.azure.net/keys/contosokey/01234567890123456789012345678901'&lt;/LI-CODE&gt;
&lt;P&gt;Then set it as the TDE protector:&lt;/P&gt;
&lt;LI-CODE lang="powershell"&gt;Set-AzSqlInstanceTransparentDataEncryptionProtector -Type AzureKeyVault -InstanceName "ContosoManagedInstanceName" -ResourceGroupName "ContosoResourceGroup" -KeyId "https://contoso.vault.azure.net/keys/contosokey/01234567890123456789012345678901" -AutoRotationEnabled $true&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Step 5: Create a Credential for the Target Blob Container&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Finally, create a SQL credential that maps the Azure Blob Storage container to SQL MI’s managed identity.&lt;/P&gt;
&lt;P&gt;Run the following statement on the SQL Managed Instance after you verify that your storage blob container has been created already:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;CREATE CREDENTIAL [https://contoso.blob.core.windows.net/myfirstcontainer]
WITH IDENTITY = 'Managed Identity';&lt;/LI-CODE&gt;
&lt;P&gt;Important notes: The credential name must exactly match the container URL. This credential is used by SQL Server during BACKUP DATABASE … TO URL.&lt;/P&gt;
&lt;P&gt;You have now successfully configured your SQL MI to be able to take copy only backups! This is an example of how your backup command should like:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;BACKUP DATABASE ... TO URL = '...' WITH COPY_ONLY, COMPRESSION;&lt;/LI-CODE&gt;
&lt;P&gt;The below sections will explain the common errors that you may run into while taking copy only backups.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Common errors that you may encounter when attempting copy-only backups:&lt;BR /&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;1) Error#1:&lt;/U&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Msg 3271, Level 16, State 1, Line 1&lt;BR /&gt;A nonrecoverable I/O error occurred on file '&amp;lt;URL to bak file&amp;gt;' Backup to URL received an exception from the remote endpoint. Exception Message: Unable to connect to the remote server.&lt;BR /&gt;Msg 3013, Level 16, State 1, Line 1&lt;BR /&gt;BACKUP DATABASE is terminating abnormally.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;BR /&gt;This error is caused by:&lt;/P&gt;
&lt;P&gt;A) An IP or a port 443 block from NSGs/firewalls.&lt;/P&gt;
&lt;P&gt;B) SQL MI is not able to reach the storage blob container due to some network misconfiguration from either side.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Please review your network settings in the storage account and your NSGs and firewall.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;2) Error#2:&lt;/U&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Msg 3201, Level 16, State 1, Line 1&lt;/P&gt;
&lt;P&gt;Cannot open backup device '&amp;lt;URL to the bak file&amp;gt;'. Operating system error 86(The specified network password is not correct.).&lt;/P&gt;
&lt;P&gt;Msg 3013, Level 16, State 1, Line 1&lt;/P&gt;
&lt;P&gt;BACKUP DATABASE is terminating abnormally.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This error is caused by misconfigured credentials or missing permissions. Please verify that your SQL MI managed identity has the "Storage Blob Data Contributor" role and the above CREATE CREDENTIAL query was executed with the correct URL name.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;3) Error#3:&lt;/U&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Msg 3202, Level 16, State 1, Line 1&lt;BR /&gt;Write on "&amp;lt;URL to bak file&amp;gt;"&amp;nbsp;failed: 1117(The request could not be performed because of an I/O device error.)&lt;BR /&gt;Msg 3013, Level 16, State 1, Line 1&lt;BR /&gt;BACKUP DATABASE is terminating abnormally.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This error occurs because your database has passed the blob storage block limit. Depending on the transfer size, a single backup file is capped at roughly 50,000 × MAXTRANSFERSIZE. So, when the individual backup file is more than that, you get this error.&lt;/P&gt;
&lt;P&gt;You need to stripe the backup into multiple files to avoid this failure of backup and make sure that MAXTRANSFERSIZE is equals to 4 MB in your TSQL command.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Example:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;BACKUP DATABASE […] TO 
URL = '&amp;lt;storage URL&amp;gt;/backup/DB_part01.bak', 
[…]
URL = '&amp;lt;storage URL&amp;gt;/backup/DB_part20.bak', 
WITH
COPY_ONLY,
COMPRESSION,
MAXTRANSFERSIZE = 4194304,
BLOCKSIZE = 65536;&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;Disclaimer&lt;/U&gt;&lt;/STRONG&gt;&lt;BR /&gt;Please note that products and options presented in this article are subject to change. This article reflects for Azure SQL Managed Instance in April 2026.&lt;/P&gt;
&lt;P&gt;I hope this article was helpful for you, please feel free to share your feedback in the comments section.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sat, 25 Apr 2026 21:57:06 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/how-to-take-copy-only-backups-with-sql-managed-instance/ba-p/4512541</guid>
      <dc:creator>ahmaddaoud</dc:creator>
      <dc:date>2026-04-25T21:57:06Z</dc:date>
    </item>
    <item>
      <title>Understanding action_id discrepancies in Azure SQL Database Audit Logs (BCM vs AL / CR / DR)</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/understanding-action-id-discrepancies-in-azure-sql-database/ba-p/4509932</link>
      <description>&lt;P&gt;&lt;STRONG&gt;Overview&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;While working with Azure SQL Database auditing in enterprise environments, you may encounter an inconsistency in how the action_id field is captured across different PaaS SQL servers.&lt;/P&gt;
&lt;P&gt;In one such scenario, a customer observed:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;PaaS Server&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;action_id observed for similar DDL statements&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Server A&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;AL, CR, DR&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Server B&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;BCM only&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;This inconsistency impacted downstream compliance pipelines, as the audit data was expected to be captured and interpreted uniformly across all servers.&lt;/P&gt;
&lt;P&gt;This article explains:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;How Azure SQL Auditing works by default&lt;/LI&gt;
&lt;LI&gt;What causes BCM to appear instead of AL/CR/DR&lt;/LI&gt;
&lt;LI&gt;How to standardize audit logs across PaaS servers&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;How Azure SQL Database Auditing Works?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Azure SQL Database auditing uses a managed and fixed audit policy at the service level.&lt;/P&gt;
&lt;P&gt;When auditing is enabled at the server level, the default auditing policy includes the following action groups:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;BATCH_COMPLETED_GROUP&lt;/LI&gt;
&lt;LI&gt;SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP&lt;/LI&gt;
&lt;LI&gt;FAILED_DATABASE_AUTHENTICATION_GROUP&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;These groups audit:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;All query execution activity&lt;/LI&gt;
&lt;LI&gt;Successful authentication attempts&lt;/LI&gt;
&lt;LI&gt;Failed authentication attempts&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;As a result, SQL batches — including DDL statements like CREATE, ALTER, or DROP on database objects — are captured under the BATCH_COMPLETED_GROUP and appear with action_id = BCM&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Why AL, CR, and DR are not captured by default?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Audit action IDs such as AL, CR and DR are considered Security / DDL-level audit events.&lt;/P&gt;
&lt;P&gt;These events are not included in the default Azure SQL auditing policy.&lt;/P&gt;
&lt;P&gt;Instead, they are generated only when the corresponding Security-related AuditActionGroups are explicitly enabled.&lt;/P&gt;
&lt;P&gt;For example:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;AuditActionGroup&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Captures&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;DATABASE_OBJECT_CHANGE_GROUP&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;CREATE / ALTER / DROP on database objects&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;DATABASE_PRINCIPAL_CHANGE_GROUP&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;User / role changes&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;DATABASE_ROLE_MEMBER_CHANGE_GROUP&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Role membership updates&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;DDL operations such as CREATE / ALTER / DROP on database objects are captured under action groups like DATABASE_OBJECT_CHANGE_GROUP.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Observed Behavior in a Newly Created Test Server&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Running the following PowerShell command on a newly provisioned logical server showed only the default audit action groups enabled.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="powershell"&gt;(Get-AzSqlServerAudit -ResourceGroupName "RGName" -ServerName "ServerName").AuditActionGroup&lt;/LI-CODE&gt;&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Therefore, DDL statements were audited but recorded as action_id = BCM&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Enabling AL / CR / DR Action IDs&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;To capture DDL operations under their respective audit action IDs, configure the required security audit action groups at the SQL Server level.&lt;/P&gt;
&lt;P&gt;For example: In this customer scenario, we executed the following command:&lt;/P&gt;
&lt;LI-CODE lang="powershell"&gt;Set-AzSqlServerAudit 
 -ResourceGroupName "RGName" 
 -ServerName "ServerName" 
 -AuditActionGroup 
 "DATABASE_PRINCIPAL_CHANGE_GROUP",
 "DATABASE_ROLE_MEMBER_CHANGE_GROUP",
 "DATABASE_OBJECT_CHANGE_GROUP"&lt;/LI-CODE&gt;
&lt;P&gt;After applying this configuration:&lt;/P&gt;
&lt;P&gt;DDL operations were captured in the audit logs as action_id = CR, AL and DR instead of BCM.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Ensuring Consistent Compliance Across PaaS Servers&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;To standardize audit logging behavior across environments:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 1: Compare AuditActionGroups&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Run the following command on all servers:&lt;/P&gt;
&lt;LI-CODE lang="powershell"&gt;(Get-AzSqlServerAudit -ResourceGroupName "&amp;lt;RG&amp;gt;" -ServerName "&amp;lt;ServerName&amp;gt;").AuditActionGroup&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Step 2: Align AuditActionGroups&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Configure all server with same AuditActionGroup values. In this case, value used was below:&lt;/P&gt;
&lt;LI-CODE lang="powershell"&gt;Set-AzSqlServerAudit 
 -ResourceGroupName "&amp;lt;RG&amp;gt;" 
 -ServerName "&amp;lt;ServerName&amp;gt;" 
 -AuditActionGroup `
 "DATABASE_PRINCIPAL_CHANGE_GROUP",
 "DATABASE_ROLE_MEMBER_CHANGE_GROUP",
 "DATABASE_OBJECT_CHANGE_GROUP"&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Step 3: Validate&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Once aligned, similar SQL statements across all PaaS servers should now generate consistent action_id values in audit logs.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Accepted values for &lt;A href="https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Furldefense.com%2Fv3%2F__https%3A%2F%2Flearn.microsoft.com%2Fen-us%2Fdotnet%2Fapi%2Fmicrosoft.azure.commands.sql.auditing.model.auditactiongroups__%3B!!Nyu6ZXf5!v9WEcJe8GgZGJM30tzome-bmFQE-ncl9S0bmX2T264tPWUaZfMA-3MKTVCRyEKkCO5c2v7ldTdpKr0TinRc%24&amp;amp;data=05%7C02%7Csuagarwal%40microsoft.com%7C92497c36fc774c3a8f9c08de93b5231b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C639110603427303355%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&amp;amp;sdata=5o4%2FErXG1YicmzaR4FS2aEaVtRzW8yos2k3UROJx%2Fa4%3D&amp;amp;reserved=0" target="_blank" rel="noopener"&gt;AuditActionGroups. Ensure appropriate groups are enabled based on your organization’s compliance needs.&lt;/A&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Accepted values:&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;BATCH_STARTED_GROUP, BATCH_COMPLETED_GROUP, APPLICATION_ROLE_CHANGE_PASSWORD_GROUP, BACKUP_RESTORE_GROUP, DATABASE_LOGOUT_GROUP, DATABASE_OBJECT_CHANGE_GROUP, DATABASE_OBJECT_OWNERSHIP_CHANGE_GROUP, DATABASE_OBJECT_PERMISSION_CHANGE_GROUP, DATABASE_OPERATION_GROUP, DATABASE_PERMISSION_CHANGE_GROUP, DATABASE_PRINCIPAL_CHANGE_GROUP, DATABASE_PRINCIPAL_IMPERSONATION_GROUP, DATABASE_ROLE_MEMBER_CHANGE_GROUP, FAILED_DATABASE_AUTHENTICATION_GROUP, SCHEMA_OBJECT_ACCESS_GROUP, SCHEMA_OBJECT_CHANGE_GROUP, SCHEMA_OBJECT_OWNERSHIP_CHANGE_GROUP, SCHEMA_OBJECT_PERMISSION_CHANGE_GROUP, SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP, USER_CHANGE_PASSWORD_GROUP, LEDGER_OPERATION_GROUP, DBCC_GROUP, DATABASE_OWNERSHIP_CHANGE_GROUP, DATABASE_CHANGE_GROUP&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Links:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/powershell/module/az.sql/get-azsqlserveraudit?view=azps-15.4.0" target="_blank" rel="noopener"&gt;Get-AzSqlServerAudit (Az.Sql) | Microsoft Learn&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Furldefense.com%2Fv3%2F__https%3A%2F%2Flearn.microsoft.com%2Fen-us%2Fpowershell%2Fmodule%2Faz.sql%2Fset-azsqlserveraudit%3Fview%3Dazps-15.4.0__%3B!!Nyu6ZXf5!v9WEcJe8GgZGJM30tzome-bmFQE-ncl9S0bmX2T264tPWUaZfMA-3MKTVCRyEKkCO5c2v7ldTdpKoyceg0A%24&amp;amp;data=05%7C02%7Csuagarwal%40microsoft.com%7C92497c36fc774c3a8f9c08de93b5231b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C639110603427328075%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&amp;amp;sdata=vCQkjF8z2J1AZZBn7tM6t4eL1HeqGinFdAoAK0XhMCI%3D&amp;amp;reserved=0" target="_blank" rel="noopener"&gt;Set-AzSqlServerAudit (Az.Sql) | Microsoft Learn&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 16 Apr 2026 11:41:59 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/understanding-action-id-discrepancies-in-azure-sql-database/ba-p/4509932</guid>
      <dc:creator>Sunaina_Agarwal</dc:creator>
      <dc:date>2026-04-16T11:41:59Z</dc:date>
    </item>
    <item>
      <title>Monitoring Azure SQL Data Sync Errors Using PowerShell</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/monitoring-azure-sql-data-sync-errors-using-powershell/ba-p/4511206</link>
      <description>&lt;P&gt;Azure SQL Data Sync is a powerful service that enables data synchronization between multiple databases across Azure SQL Database and on‑premises SQL Server environments. It supports hybrid architectures and distributed applications by allowing selected data to synchronize bi‑directionally between hub and member databases using a hub‑and‑spoke topology.&lt;/P&gt;
&lt;P&gt;However, one of the most common operational challenges faced by support engineers and customers using Azure SQL Data Sync is:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;❗ Lack of proactive monitoring for sync failures or errors&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;By default, Azure SQL Data Sync does not provide native alerting mechanisms that notify administrators when synchronization operations fail or encounter issues. This can result in silent data drift or synchronization delays that may go unnoticed in production environments.&lt;/P&gt;
&lt;P&gt;In this blog, we’ll walk through how to monitor Azure SQL Data Sync activity and detect synchronization errors using Azure PowerShell commands.&lt;/P&gt;
&lt;H2&gt;Why Monitoring Azure SQL Data Sync Matters&lt;/H2&gt;
&lt;P&gt;Azure SQL Data Sync works by synchronizing data between:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Hub Database (must be Azure SQL Database)&lt;/LI&gt;
&lt;LI&gt;Member Databases (Azure SQL Database or SQL Server)&lt;/LI&gt;
&lt;LI&gt;Sync Metadata Database (stores sync configuration and logs)&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;All synchronization activity—including errors, failures, and successes—is logged internally within the Sync Metadata Database and exposed through Azure SQL Sync Group logs.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Monitoring these logs enables:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Detection of sync failures&lt;/LI&gt;
&lt;LI&gt;Identification of schema mismatches&lt;/LI&gt;
&lt;LI&gt;Validation of sync completion&lt;/LI&gt;
&lt;LI&gt;Troubleshooting of sync group issues&lt;/LI&gt;
&lt;LI&gt;Verification of last successful sync activity&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Prerequisites&lt;/H2&gt;
&lt;P&gt;Before monitoring Azure SQL Data Sync activity, ensure the following:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Azure PowerShell module (&lt;STRONG&gt;Az.Sql&lt;/STRONG&gt;) is installed&lt;/LI&gt;
&lt;LI&gt;You have access to the Azure SQL Data Sync resources&lt;/LI&gt;
&lt;LI&gt;Proper authentication and subscription context are configured&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Install and import the required module if not already available:&lt;/P&gt;
&lt;LI-CODE lang="powershell"&gt;# Install Azure PowerShell module if not already installed
Install-Module -Name Az -Repository PSGallery -Force

# Import the SQL module
Import-Module Az.Sql&lt;/LI-CODE&gt;
&lt;P&gt;Authenticate to Azure:&lt;/P&gt;
&lt;LI-CODE lang="powershell"&gt;# Login to Azure
Connect-AzAccount -TenantId "&amp;lt;tenant-id&amp;gt;"

# Set subscription context
Set-AzContext -SubscriptionId "&amp;lt;subscription-id&amp;gt;"&lt;/LI-CODE&gt;
&lt;P&gt;These commands enable access to Azure SQL Sync Group monitoring operations.&lt;/P&gt;
&lt;H2&gt;Monitoring Sync Group Status&lt;/H2&gt;
&lt;P&gt;To retrieve Sync Group details, define the required variables:&lt;/P&gt;
&lt;LI-CODE lang="powershell"&gt;# Define variables
$resourceGroup = "rg-datasync-demo"
$serverName = "&amp;lt;hub-server-name&amp;gt;"
$databaseName = "HubDatabase"
$syncGroupName = "SampleSyncGroup"

# Get sync group details
Get-AzSqlSyncGroup -ResourceGroupName $resourceGroup `
-ServerName $serverName `
-DatabaseName $databaseName `
-SyncGroupName $syncGroupName | Format-List&lt;/LI-CODE&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Note:&lt;BR /&gt;The LastSyncTime property returned by Get-AzSqlSyncGroup may sometimes display a value such as &lt;STRONG&gt;1/1/0001&lt;/STRONG&gt;, even when synchronization operations are completing successfully.&lt;BR /&gt;To obtain accurate synchronization timestamps, it is recommended to use Sync Group Logs instead.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H2&gt;Monitoring Sync Activity Using Logs (Recommended)&lt;/H2&gt;
&lt;P&gt;To monitor synchronization activity and retrieve detailed sync status, use:&lt;/P&gt;
&lt;LI-CODE lang="powershell"&gt;# Get sync logs for the last 24 hours
$startTime = (Get-Date).AddHours(-24).ToString("yyyy-MM-ddTHH:mm:ssZ")
$endTime = (Get-Date).ToString("yyyy-MM-ddTHH:mm:ssZ")

Get-AzSqlSyncGroupLog -ResourceGroupName $resourceGroup `
-ServerName $serverName `
-DatabaseName $databaseName `
-SyncGroupName $syncGroupName `
-StartTime $startTime `
-EndTime $endTime&lt;/LI-CODE&gt;
&lt;P&gt;This command retrieves:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Sync operation timestamps&lt;/LI&gt;
&lt;LI&gt;Sync status&lt;/LI&gt;
&lt;LI&gt;Error messages&lt;/LI&gt;
&lt;LI&gt;Activity details&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Sync Group Logs provide more reliable monitoring information than the Sync Group status output alone.&lt;/P&gt;
&lt;H2&gt;Retrieving the Last Successful Sync Time&lt;/H2&gt;
&lt;P&gt;To determine the most recent successful synchronization operation:&lt;/P&gt;
&lt;LI-CODE lang="powershell"&gt;# Get the most recent successful sync timestamp
$startTime = (Get-Date).AddDays(-7).ToString("yyyy-MM-ddTHH:mm:ssZ")
$endTime = (Get-Date).ToString("yyyy-MM-ddTHH:mm:ssZ")

Get-AzSqlSyncGroupLog -ResourceGroupName $resourceGroup `
-ServerName $serverName `
-DatabaseName $databaseName `
-SyncGroupName $syncGroupName `
-StartTime $startTime `
-EndTime $endTime |
Where-Object { $_.Details -like "*completed*" -or $_.Type -eq "Success" } |
Select-Object -First 1 Timestamp, Type, Details&lt;/LI-CODE&gt;
&lt;P&gt;This helps administrators validate whether synchronization is occurring as expected across the sync topology.&lt;/P&gt;
&lt;H2&gt;Filtering for Synchronization Errors&lt;/H2&gt;
&lt;P&gt;To identify failed or problematic sync operations:&lt;/P&gt;
&lt;LI-CODE lang="powershell"&gt;# Get only error logs
Get-AzSqlSyncGroupLog -ResourceGroupName $resourceGroup `
-ServerName $serverName `
-DatabaseName $databaseName `
-SyncGroupName $syncGroupName `
-StartTime $startTime `
-EndTime $endTime |
Where-Object { $_.LogLevel -eq "Error" }&lt;/LI-CODE&gt;
&lt;P&gt;Filtering logs by error type allows for:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Rapid identification of failed sync attempts&lt;/LI&gt;
&lt;LI&gt;Analysis of failure causes&lt;/LI&gt;
&lt;LI&gt;Early detection of data consistency risks&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Key Takeaways&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;Azure SQL Data Sync does not provide native alerting for sync failures&lt;/LI&gt;
&lt;LI&gt;Sync Group Logs offer detailed monitoring of sync operations&lt;/LI&gt;
&lt;LI&gt;Get-AzSqlSyncGroupLog provides accurate timestamps and status&lt;/LI&gt;
&lt;LI&gt;Monitoring logs enables detection of silent sync failures&lt;/LI&gt;
&lt;LI&gt;PowerShell can be used to proactively monitor synchronization health&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;References&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://github.com/mhaywardhill/azure-sql-datasync-error-monitoring/tree/main/monitoring" data-tabster="{&amp;quot;restorer&amp;quot;:{&amp;quot;type&amp;quot;:1}}" target="_blank"&gt;Azure SQL Data Sync Error Monitoring GitHub Repository&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/database/sql-data-sync-data-sql-server-sql-database?view=azuresql" data-tabster="{&amp;quot;restorer&amp;quot;:{&amp;quot;type&amp;quot;:1}}" target="_blank"&gt;What is SQL Data Sync for Azure?&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Tue, 14 Apr 2026 13:27:59 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/monitoring-azure-sql-data-sync-errors-using-powershell/ba-p/4511206</guid>
      <dc:creator>Mohamed_Baioumy_MSFT</dc:creator>
      <dc:date>2026-04-14T13:27:59Z</dc:date>
    </item>
    <item>
      <title>Fixing “There is not enough space on the disk” during Azure Data Sync initial sync (On‑prem ➜ Azure)</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/fixing-there-is-not-enough-space-on-the-disk-during-azure-data/ba-p/4510866</link>
      <description>&lt;P&gt;When you run an&amp;nbsp;&lt;STRONG&gt;initial&lt;/STRONG&gt; (first-time) sync from an on‑premises SQL Server database to &lt;STRONG&gt;Azure SQL Database&lt;/STRONG&gt; using &lt;STRONG&gt;SQL Data Sync&lt;/STRONG&gt;, the local agent may fail with a disk-space error—even when the disk “looks” like it has free space. The reason is that the initial sync can generate &lt;STRONG&gt;large temporary files&lt;/STRONG&gt; in the Windows &lt;STRONG&gt;TEMP&lt;/STRONG&gt; location used by the Data Sync Agent.&lt;/P&gt;
&lt;P&gt;This post explains the symptom, what’s happening under the hood, and the most practical mitigation:&amp;nbsp;&lt;STRONG&gt;move the Data Sync Agent’s TEMP/TMP to a drive with sufficient space&lt;/STRONG&gt; and restart the service.&lt;/P&gt;
&lt;H2&gt;Symptom&lt;/H2&gt;
&lt;P&gt;During an initial sync (commonly on-premises ➜ Azure), the sync fails while applying a batch file.&lt;/P&gt;
&lt;H2&gt;Error&lt;/H2&gt;
&lt;P&gt;You may see an error similar to:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Sync failed with the exception:&lt;BR /&gt;“An unexpected error occurred when applying batch file … .batch. See the inner exception for more details. Inner exception: &lt;STRONG&gt;There is not enough space on the disk&lt;/STRONG&gt; …”&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Microsoft Learn also calls out “disk insufficient space” scenarios for SQL Data Sync and points to the&amp;nbsp;&lt;STRONG&gt;%TEMP%&lt;/STRONG&gt; directory as the key location to check.&lt;/P&gt;
&lt;H2&gt;What’s actually happening (Root Cause)&lt;/H2&gt;
&lt;H3&gt;1) Initial sync uses temp files on the agent machine&lt;/H3&gt;
&lt;P&gt;During initialization, the local agent can &lt;STRONG&gt;load data and store it as temp files&lt;/STRONG&gt; in the system temp folder. This is explicitly called out in the Azure SQL Data Sync scalability guidance.&lt;/P&gt;
&lt;H3&gt;2) The agent can generate&amp;nbsp;&lt;EM&gt;more&lt;/EM&gt; than “just the batch files”&lt;/H3&gt;
&lt;P&gt;In practice, you’ll often see:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Batch files&lt;/STRONG&gt; (e.g., sync_*.batch)&lt;/LI&gt;
&lt;LI&gt;Extra temp files under folders like &lt;STRONG&gt;MAT_ / MATS_&lt;/STRONG&gt; that are used for internal processing (commonly described as “sorting”/intermediate work).&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Internal field experience shared in the Data Sync support channel highlights that the MAT/MATS files can be &lt;STRONG&gt;much larger&lt;/STRONG&gt; than the batch files—sometimes &lt;STRONG&gt;8–10× larger&lt;/STRONG&gt; than the data being synced for that table (especially during initialization).&lt;/P&gt;
&lt;H3&gt;3) Why “I still have free disk space” can be misleading&lt;/H3&gt;
&lt;P&gt;If your Data Sync Agent’s TEMP points to a system drive (often C:), it can fill quickly with temp batches + MAT/MATS files during the first sync—particularly for large tables or many tables being initialized. The Azure SQL Data Sync “large scale” guidance recommends ensuring the temp folder has enough space &lt;EM&gt;before&lt;/EM&gt; starting initialization and notes you &lt;STRONG&gt;can move TEMP/TMP&lt;/STRONG&gt; to another drive.&lt;/P&gt;
&lt;H2&gt;Mitigation (Recommended)&lt;/H2&gt;
&lt;H3&gt;Option A — Move TEMP/TMP to a larger drive (recommended)&lt;/H3&gt;
&lt;P&gt;The &lt;STRONG&gt;Microsoft Azure Blog&lt;/STRONG&gt; guidance for large-scale initialization is clear: move the temp folder by setting TEMP and TMP environment variables and &lt;STRONG&gt;restart the sync service&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H4&gt;Key point: change the variables for the&amp;nbsp;&lt;STRONG&gt;same account running the Data Sync Agent service&lt;/STRONG&gt;&lt;/H4&gt;
&lt;P&gt;Environment variables exist at &lt;STRONG&gt;user scope&lt;/STRONG&gt; and &lt;STRONG&gt;machine scope&lt;/STRONG&gt;, and the effective TEMP location depends on which account the agent service runs under.&lt;/P&gt;
&lt;P&gt;A simple PowerShell approach (run elevated) is to read and set the variables at the appropriate scope. (Example shown below uses the standard .NET environment APIs.)&lt;/P&gt;
&lt;LI-CODE lang=""&gt;# Run in Administrator mode
# Get current values
[Environment]::GetEnvironmentVariable("TEMP","User")
[Environment]::GetEnvironmentVariable("TEMP","Machine")
# Set new values (examples)
[Environment]::SetEnvironmentVariable("TEMP","D:\TempUser","User")
[Environment]::SetEnvironmentVariable("TMP" ,"D:\TempUser","User")
# or machine scope:
[Environment]::SetEnvironmentVariable("TEMP","D:\TempMachine","Machine")
[Environment]::SetEnvironmentVariable("TMP" ,"D:\TempMachine","Machine")&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Important:&lt;/STRONG&gt; After updating TEMP/TMP, &lt;STRONG&gt;restart the SQL Data Sync agent service&lt;/STRONG&gt; so it picks up the new environment settings.&lt;/P&gt;
&lt;H3&gt;Option B — If you can’t log in as the service account: update TEMP/TMP in the registry for that account&lt;/H3&gt;
&lt;P&gt;If you need to change TEMP/TMP for a specific account without interactive logon, you can update the &lt;STRONG&gt;user environment variables&lt;/STRONG&gt; stored in the registry.&lt;/P&gt;
&lt;P&gt;General Windows guidance indicates:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;User environment variables live under HKEY_CURRENT_USER\Environment (and for other users, under that user’s SID hive loaded under HKEY_USERS).&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;A common approach is:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Identify the service account SID (example commands such as WMIC are often used in practice).&lt;/LI&gt;
&lt;LI&gt;Open Registry Editor&lt;/LI&gt;
&lt;LI&gt;Navigate to:&lt;BR /&gt;HKEY_USERS\&amp;lt;SID&amp;gt;\Environment&lt;/LI&gt;
&lt;LI&gt;Update TEMP and TMP to a path on a drive with sufficient space.&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Restart the Data Sync service.&lt;/P&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;H3&gt;Option C — Clean up leftover sync temp files (when sync is NOT running)&lt;/H3&gt;
&lt;P&gt;In some cases, the “disk out of space” condition is caused by &lt;STRONG&gt;leftover sync files&lt;/STRONG&gt; that were not removed (for example, if something had files open during deletion). Microsoft Learn suggests manually deleting sync files from %temp% and cleaning subdirectories &lt;STRONG&gt;only when sync is not in progress&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H2&gt;Validation checklist (after the change)&lt;/H2&gt;
&lt;P&gt;After moving TEMP/TMP and restarting the service, confirm:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;New temp path is being used&lt;/STRONG&gt;&lt;BR /&gt;Initiate sync and check that new sync_*.batch / temp artifacts appear under the new folder.&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Sufficient free space exists for initialization&lt;/STRONG&gt;&lt;BR /&gt;Especially for large tables, ensure the chosen drive can accommodate temp growth during the first sync. &lt;A href="https://azure.microsoft.com/en-us/blog/sync-sql-data-in-large-scale-using-azure-sql-data-sync/" target="_blank"&gt;&amp;nbsp;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Rerun initial sync&lt;/STRONG&gt;&lt;BR /&gt;Retry the initial sync after making the change.&amp;nbsp;&lt;/LI&gt;
&lt;/OL&gt;
&lt;H2&gt;Classification&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Symptom type:&lt;/STRONG&gt; Agent side / initialization failure&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Primary root cause:&lt;/STRONG&gt; Insufficient disk space on the &lt;STRONG&gt;TEMP&lt;/STRONG&gt; location used by the Data Sync Agent during initial sync temp-file generation&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Fix type:&lt;/STRONG&gt; Configuration / operational (move TEMP/TMP to a larger drive + restart agent service)&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;a { text-decoration: none; color: #464feb; } tr th, tr td { border: 1px solid #e6e6e6; } tr th { background-color: #f5f5f5; }&lt;/P&gt;
&lt;H2&gt;Helpful references&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/database/sql-data-sync-troubleshoot?view=azuresql" data-tabster="{&amp;quot;restorer&amp;quot;:{&amp;quot;type&amp;quot;:1}}" target="_blank"&gt;Troubleshoot SQL Data Sync (Microsoft Learn)&lt;/A&gt;&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://azure.microsoft.com/en-us/blog/sync-sql-data-in-large-scale-using-azure-sql-data-sync/" data-tabster="{&amp;quot;restorer&amp;quot;:{&amp;quot;type&amp;quot;:1}}" target="_blank"&gt;Sync SQL data in large scale using Azure SQL Data Sync (Microsoft Azure Blog)&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/azure-sql/database/sql-data-sync-agent-overview?view=azuresql" data-tabster="{&amp;quot;restorer&amp;quot;:{&amp;quot;type&amp;quot;:1}}" target="_blank"&gt;Data Sync Agent for SQL Data Sync (Microsoft Learn)&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Mon, 13 Apr 2026 14:31:07 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/fixing-there-is-not-enough-space-on-the-disk-during-azure-data/ba-p/4510866</guid>
      <dc:creator>Mohamed_Baioumy_MSFT</dc:creator>
      <dc:date>2026-04-13T14:31:07Z</dc:date>
    </item>
    <item>
      <title>Troubleshooting Azure SQL Data Sync Failure: SQL Error 8106 During Bulk Insert</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/troubleshooting-azure-sql-data-sync-failure-sql-error-8106/ba-p/4509665</link>
      <description>&lt;P&gt;Azure SQL Data Sync is widely used to maintain consistency across distributed databases in hub–member topologies. However, synchronization may occasionally fail due to schema mismatches between participating databases — even when everything appears correctly configured at first glance.&lt;/P&gt;
&lt;P&gt;In this post, we’ll walk through a real-world troubleshooting scenario involving a Data Sync failure caused by a schema inconsistency related to an &lt;STRONG&gt;IDENTITY column&lt;/STRONG&gt;, and how it was mitigated.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Sample Error:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-teams="true"&gt;&lt;EM&gt;sync_7726d6cb22124c0f901192c434f49106bd618f8ab16343b2adc03250f8367ff4\3953fb7d-1dba-4656-8150-83153d5d019b.batch. See the inner exception for more details. Inner exception: Failed to execute the command 'BulkInsertCommand' for table 'schema.table_name'; the transaction was rolled back. Ensure that the command syntax is correct. Inner exception: SqlException ID: e19b3677-d67e-4c8e-bc49-13d3df61ad0e, Error Code: -2146232060 - SqlError Number:8106, Message: SQL error with code 8106 For more information, provide tracing ID ‘92e76130-f80a-4372-9a48-ec0ede8b0288’ to customer support."&lt;/EM&gt;&amp;nbsp; &amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;Scenario Overview&lt;/H2&gt;
&lt;P&gt;A synchronization operation began failing for a specific table within an Azure SQL Data Sync group. The failure was observed during the sync process when applying changes using a batch file.&lt;/P&gt;
&lt;P&gt;The error surfaced as part of a failed &lt;STRONG&gt;&lt;EM&gt;BulkInsertCommand&lt;/EM&gt;&lt;/STRONG&gt; execution on a synced table, causing the transaction to roll back.&lt;/P&gt;
&lt;P&gt;Further investigation revealed the following SQL exception:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;SqlError Number: 8106&lt;/STRONG&gt;&lt;BR /&gt;&lt;EM&gt;Table does not have the identity property. Cannot perform SET operation.&lt;/EM&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H2&gt;Initial Troubleshooting Steps&lt;/H2&gt;
&lt;P&gt;Before identifying the root cause, the following actions were taken:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The affected table was removed from the sync group.&lt;/LI&gt;
&lt;LI&gt;A sync operation was triggered.&lt;/LI&gt;
&lt;LI&gt;The table was re-added to the sync group.&lt;/LI&gt;
&lt;LI&gt;Sync was triggered again.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Despite performing these steps, the issue persisted with the same error.&lt;/P&gt;
&lt;P&gt;This indicated that the failure was not related to sync metadata or temporary configuration inconsistencies.&lt;/P&gt;
&lt;H2&gt;Root Cause Analysis&lt;/H2&gt;
&lt;P&gt;After reviewing the table definitions across the sync topology, it was discovered that:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;The synchronized table had an&amp;nbsp;&lt;STRONG&gt;IDENTITY column defined on one side of the topology (Hub or Member)&lt;/STRONG&gt; but &lt;STRONG&gt;not on the other&lt;/STRONG&gt;.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This schema mismatch led to the sync service attempting to apply SET IDENTITY_INSERT operations during the bulk insert phase — which failed on the database where the column lacked the identity property.&lt;/P&gt;
&lt;P&gt;Azure SQL Data Sync relies on consistent schema definitions across all participating databases. Any deviation — particularly involving identity columns — can interrupt data movement operations.&lt;/P&gt;
&lt;H2&gt;Mitigation Approach&lt;/H2&gt;
&lt;P&gt;To resolve the issue, the following corrective steps were applied:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Remove the affected table from the sync group and save the configuration.&lt;/LI&gt;
&lt;LI&gt;Refresh the sync schema.&lt;/LI&gt;
&lt;LI&gt;Recreate the table to include the appropriate IDENTITY property.&lt;/LI&gt;
&lt;LI&gt;Add the corrected table back to the sync group.&lt;/LI&gt;
&lt;LI&gt;Trigger a new sync operation.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;These steps ensured that the table definitions were aligned across all sync participants, allowing the synchronization process to proceed successfully.&lt;/P&gt;
&lt;H2&gt;Best Practices to Avoid Similar Issues&lt;/H2&gt;
&lt;P&gt;To prevent identity-related sync failures in Azure SQL Data Sync:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;✅ Ensure table schemas are &lt;STRONG&gt;identical&lt;/STRONG&gt; across all participating databases before onboarding them into a sync group.&lt;/LI&gt;
&lt;LI&gt;✅ Pay special attention to:
&lt;UL&gt;
&lt;LI&gt;IDENTITY properties&lt;/LI&gt;
&lt;LI&gt;Primary keys&lt;/LI&gt;
&lt;LI&gt;Data types&lt;/LI&gt;
&lt;LI&gt;Nullable constraints&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;✅ Always validate schema consistency when:
&lt;UL&gt;
&lt;LI&gt;Adding new tables to a sync group&lt;/LI&gt;
&lt;LI&gt;Modifying existing table definitions&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Final Thoughts&lt;/H2&gt;
&lt;P&gt;Schema mismatches — especially those involving identity columns — are a common but often overlooked cause of Data Sync failures. By ensuring consistent table definitions across your hub and member databases, you can significantly reduce the risk of synchronization errors and maintain reliable data movement across regions.&lt;/P&gt;</description>
      <pubDate>Wed, 08 Apr 2026 15:55:41 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/troubleshooting-azure-sql-data-sync-failure-sql-error-8106/ba-p/4509665</guid>
      <dc:creator>Mohamed_Baioumy_MSFT</dc:creator>
      <dc:date>2026-04-08T15:55:41Z</dc:date>
    </item>
  </channel>
</rss>

