sqlserver
71 TopicsSQL Server 2016 Extended Security Updates: Stay Protected While You Modernize
SQL Server 2016 reaches the end of extended support on July 14, 2026. After that date, instances that remain on SQL Server 2016 no longer receive regular security updates unless they are covered through Extended Security Updates (ESUs)). ESUs provide a time-bound security bridge for customers who need to maintain existing workloads while they upgrade to a supported SQL Server release or modernize to Azure SQL. SQL Server 2016 Extended Security Updates can be managed across multiple deployment models, including SQL Server enabled by Azure Arc for on-premises and other clouds, and SQL Server on Azure Virtual Machines. This provides a consistent protection path while customers assess modernization options and operational readiness. Today, we are making the Extended Security Updates subscription experience available in Azure so customers can enroll ahead of SQL Server 2016 reaching end of support, and be ready to receive Extended Security Updates when they are released. Why this matters now SQL Server follows a fixed lifecycle policy with mainstream support followed by extended support. Once SQL Server 2016 exits extended support, Extended Security Updates become the only for continued security coverage on that version. Extended Security Updates are intended as a temporary option for risk reduction, not as a long-term alternative to upgrade or modernization. For many production environments, the constraint is not awareness of the deadline but the complexity of the upgrade path. Application dependencies, validation requirements, change windows, and compliance controls sometimes make immediate migration impractical. Extended Security Updates help teams maintain security coverage during that transition period while they sequence remediation, testing, and platform changes. How SQL Server 2016 Extended Security Updates work Support window: SQL Server 2016 exits extended support on July 14, 2026. Extended Security Updates are available for up to three additional years, with coverage periods defined by the SQL Server 2016 lifecycle schedule through July 17, 2029. Supported scope and update model Eligible versions: SQL Server 2016. Extended Security Updates are also available for SQL Server 2014 until July 12, 2027. Eligible editions: Standard and Enterprise Update content: Extended Security Updates deliver critical security updates when applicable. They do not include new features, non-security bug fixes, non-critical security updates, or design changes. Operational note: SQL Server ESUs are not published on a fixed monthly cadence. They are released when qualifying vulnerabilities require a release. For Azure Arc-connected environments, Extended Security Updates subscriptions can be aligned to the deployment model, including virtual cores for VM-based deployments and physical cores for host-based scenarios. This gives organizations flexibility to match ESU coverage to how SQL Server is deployed and managed. How to acquire Extended Security Updates coverage Customers can acquire SQL Server ESU coverage in different ways depending on where SQL Server is running and how they prefer to purchase. For on-premises, edge, and other cloud environments, SQL Server enabled by Azure Arc provides the control plane to onboard instances, manage eligibility, and apply ESU subscription settings. For workloads already running on Azure Virtual Machines, customers can subscribe to ESU coverage through Azure-based controls. Customers can purchase that coverage as pay-as-you-go through Azure or through Volume Licensing on an annual basis for eligible licenses with active Software Assurance. When customers choose Volume Licensing, Azure Arc registration is still required to activate access to ESUs. SQL Server enabled by Azure Arc: Use Azure Arc to onboard eligible SQL Server instances outside Azure, manage Extended Security Updates subscription settings, and support both connected and qualifying disconnected scenarios. SQL Server on Azure Virtual Machines: Use Azure-based controls to subscribe to Extended Security Updates coverage for workloads running on Azure Virtual Machines. For SQL Server 2016, this now requires a paid ESU subscription rather than the previous no-additional-cost experience. Supported regions: Subscribing to Extended Security Updates for SQL Server on Azure VMs is only available in the supported regions listed. To subscribe to ESUs in an unsupported region, contact Microsoft Support to determine the appropriate ESU acquisition path. Volume Licensing: If you cannot subscribe to Extended Security Updates via Azure Arc, you can purchase through the Volume Licensing channel on an annual basis for eligible licenses with active Software Assurance. Talk to your Microsoft seller for more information. Azure Arc registration is still required to activate access to ESUs. Migrate to Azure SQL: Customers that are ready to modernize further can move to Azure SQL Database or Azure SQL Managed Instance, which removes Extended Security Updates dependency by moving to fully supported, cloud-managed SQL services. The following diagram summarizes how customers can obtain SQL Server 2016 Extended Security Updates coverage through Azure Arc and Azure Virtual Machines. What to do next Organizations still running SQL Server 2016 should use the remaining support window to assess estate readiness, determine the right Extended Security Updates subscription model, and define the target modernization path for each workload. For some environments, that means upgrading in place to a supported SQL Server version. For others, it means migrating and upgrading to Azure Virtual Machines or Azure SQL to simplify long-term operations. The important step is to make the transition plan executable before support ends. Learn more SQL Server end of support options SQL Server Extended Security Updates enabled by Azure Arc SQL Server enabled by Azure Arc Extend support for SQL Server with Azure VM SQL Server on Azure VM overview Migrate to Azure SQL1.1KViews0likes6CommentsAnnouncing Microsoft.Data.SqlClient 7.0.2 and 6.1.6
We are pleased to announce the release of Microsoft.Data.SqlClient 7.0.2 and 6.1.6, stable servicing updates now available on NuGet. Both releases include: WAM broker support for supported Microsoft Entra ID authentication modes on Windows TDS parsing security hardening with strict data-length bounds checks Key bug fixes, including a SqlDataReader null-reference path and an Always Encrypted signature verification cache fix Install or update from NuGet: dotnet add package Microsoft.Data.SqlClient --version 7.0.2 or dotnet add package Microsoft.Data.SqlClient --version 6.1.6 Full release notes: 7.0.2: https://github.com/dotnet/SqlClient/releases/tag/v7.0.2 6.1.6: https://github.com/dotnet/SqlClient/releases/tag/v6.1.6 What's in these releases WAM broker support for supported Entra ID authentication modes (Windows) Both servicing releases add support for the Web Account Manager (WAM) broker in supported Entra ID authentication flows on Windows. This enables OS-brokered token handling, better single sign-on behavior with the signed-in Windows account, and improved support for Conditional Access and Windows Hello scenarios. For application code, this is exposed through ActiveDirectoryAuthenticationProviderOptions, including the UseWamBroker property. Hardened TDS token parsing The TDS parser now validates declared token data lengths against the available input buffer before reading. This improves resilience against malformed or hostile protocol payloads and helps prevent out-of-bounds token parsing behavior. For well-formed SQL Server responses, behavior is unchanged. SqlDataReader null-reference fix These releases include a fix for a SqlDataReader null-reference path in buffer-based reads. Calls that previously could fail with NullReferenceException now correctly surface argument validation errors. Always Encrypted signature-cache fix The Always Encrypted column master key signature verification cache logic was corrected so cached verification results are read and applied using the correct key and value. This prevents stale or mismatched cache outcomes from being treated as valid signature verification results. Additional note for 7.0.2 users Starting with version 7.0.2, Microsoft.Data.SqlClient and companion extension packages are version-aligned to 7.0.2. If your application references extension packages (for example Microsoft.Data.SqlClient.Extensions.Azure), upgrade them to the same version for compatibility. Getting started If you are new to Microsoft.Data.SqlClient, check out the introduction documentation: https://learn.microsoft.com/sql/connect/ado-net/introduction-microsoft-data-sqlclient-namespace For users of System.Data.SqlClient, see the porting cheat sheet: https://github.com/dotnet/SqlClient/blob/main/porting-cheat-sheet.md If you encounter any issues, please report them on GitHub: https://github.com/dotnet/SqlClient/issues293Views0likes0CommentsMicrosoft Django backend for SQL Server - mssql-django 1.7.3 is now available
We are happy to announce the release of mssql-django 1.7.3. This release improves SQL Server connection compatibility for modern authentication scenarios and fixes a subclassing edge case in backend server-property caching. Highlights 1) Authentication parsing and connection string handling improvements We fixed how extra_params authentication settings are interpreted and now parse ODBC-style key/value segments more robustly. What changed: Authentication mode is parsed from extra_params using a spec-aligned parser. Trusted_Connection and SSPI injection now respects explicit Authentication= modes. Password injection behavior is driven by authentication mode, so password-based modes still receive PWD correctly. Parser behavior is hardened for cases like braced values, embedded semicolons, escaped braces, whitespace, and empty values. Why it matters: Prevents invalid combinations such as appending Trusted_Connection=yes when an explicit authentication mode is provided. Avoids ODBC driver failures (including FA001) in authentication flows such as ActiveDirectoryIntegrated. Improves predictability for advanced connection-string configurations. 2) Server-property cache fix for DatabaseWrapper subclasses We fixed a KeyError when subclassing DatabaseWrapper and accessing server-property cached values. What changed: Replaced mutable default-argument cache patterns with explicit class-level cache dictionaries. Added regression coverage for subclass access paths. Why it matters: Custom backend wrapper subclasses now behave correctly when reading cached server properties. Prevents runtime failures in extensibility scenarios. Upgrade pip install --upgrade mssql-django==1.7.3 If you are building an application that uses Entra authentication, you'll want this as your minimum version. Compatibility 1.7.3 continues the same compatibility range introduced in 1.7.x: Django 3.2 through 6.0 Python 3.8 through 3.14 All supported versions of Microsoft SQL Thank You Thank you to everyone who reported issues, validated fixes, and contributed improvements. As always, please open an issue if you hit regressions or have connection/authentication scenarios you want us to look into.103Views0likes0Commentsmssql-python 1.9.0: Row-friendly Bulk Copy, smarter NULL parameters, and a more portable wheel
We just shipped mssql-python 1.9.0, the official Microsoft SQL driver for Python. This release focuses on day-to-day ergonomics for data loading, a long-standing correctness gap around NULL parameter binding, and a build change that makes the published wheels work on clean macOS and Linux machines. pip install --upgrade mssql-python Highlights Bulk Copy now accepts Row objects (and lists) Bulk Copy previously required tuples. In 1.9.0 you can hand it Row objects straight from a SELECT, or plain lists, and the driver converts each row to a tuple internally before passing data to the Rust backend. rows = source_cursor.execute( "SELECT id, display_name, created_at FROM users" ).fetchall() target_cursor.bulkcopy("staging.users", rows) The common "fetch from one table, bulk-insert into another" pattern just works, with no manual row reshaping and no type errors on the boundary. NULL parameters now resolve to the right SQL type When you bound None to a parameter, the driver used to fall back to SQL_VARCHAR. That was fine for character columns and quietly wrong for everything else, especially VARBINARY and all-NULL columns where the server had no other type signal to lean on. 1.9.0 adds a thread-safe per-statement cache for SQLDescribeParam results, so NULL parameters resolve to the parameter's actual declared type. The cache is invalidated when a new statement is prepared, which also cuts redundant round-trips to the server during repeated executions of the same prepared statement. simdutf is now statically linked into the extension The published wheels (especially the macOS universal2 wheel) previously dynamically linked simdutf against a path that only existed on the CI build machine. On a clean install, import mssql_python could fail with missing-symbol or dlopen errors. The build no longer calls find_package(simdutf). FetchContent is used unconditionally, simdutf is built as a static library, and its symbols are embedded directly in the extension. There is nothing for end users to do; reinstall the wheel and the import works on a clean machine. Thanks to @edgarrmondragon for the contribution. Bug fixes worth calling out executemany with large Decimal values. Batch inserts of Decimal values larger than the SQL Server MONEY range raised an SQL_C_NUMERIC type-mismatch at runtime. executemany now binds DECIMAL / NUMERIC parameters as SQL_C_CHAR and sizes the column to fit the longest string representation, so large-decimal batches (including NULLs and multi-column inserts) succeed. Exception pickle round-trips. ConnectionStringParseError and the DB-API exception subclasses now implement __reduce__, so driver exceptions survive pickle / copy.deepcopy with every attribute intact. multiprocessing, distributed task queues, and anything that ships exceptions across process boundaries no longer lose context on the way through. nextset() and PRINT output. nextset() now collects diagnostic messages whenever SQL returns SQL_SUCCESS_WITH_INFO. Previously, PRINT output from secondary result sets in multi-statement batches and stored procedures was silently dropped after the first set. executemany data-at-execution path with Row objects. The DAE fallback used by large columns such as varchar(max) only recognized primitive types, so passing Row objects in that path failed. The fallback now converts Row to a tuple before mapping types. Fetch methods now type-check under ty. Catalog and metadata result-set handling no longer monkey-patches fetchone, fetchmany, and fetchall as instance attributes. A cached _column_map is built instead, so the fetch APIs stay proper class methods and static type checkers like ty stop tripping on cursor fetch calls. Upgrading For most users, pip install --upgrade mssql-python is all you need. If you had any workarounds for NULL parameter typing (manually setting inputsizes, casting in SQL, or sending sentinel values), you can drop it. If you were converting fetched rows to tuples before handing them to bulkcopy or executemany, that's no longer required either. Thanks Thanks to everyone who filed issues, sent repros, and reviewed PRs in this cycle. The NULL parameter fix, the Row handling in Bulk Copy and executemany, and the simdutf linking change all came directly from user-reported scenarios, and the simdutf change was a community contribution from @edgarrmondragon. Full changelog and PR list: microsoft/mssql-python releases.270Views0likes0Commentsmssql-python 1.8.0: friendlier Row access, Bulk Copy with MSI, and a refreshed ODBC driver
We just shipped mssql-python 1.8.0, the official Microsoft SQL Server driver for Python. This release focuses on day-to-day ergonomics, a long-requested authentication option for Bulk Copy, and a refresh of the bundled ODBC driver. pip install --upgrade mssql-python Highlights Row objects now support string-key indexing Row already supported integer indexing and attribute access. In 1.8.0 you can also index by column name, which is the pattern most users reach for first: cursor.execute("SELECT id, display_name FROM users WHERE id = ?", [42]) row = cursor.fetchone() row[0] # 42 - by index row.display_name # 'Ada' - by attribute row["display_name"] # 'Ada' - new in 1.8.0 If you set cursor.lowercase = True, string-key lookups become case-insensitive too, matching the casing behavior of attribute access. ActiveDirectoryMSI authentication for Bulk Copy Bulk Copy operations now support Authentication=ActiveDirectoryMSI, so workloads running with a managed identity (Azure VMs, App Service, Functions, Container Apps, AKS) can stream bulk inserts to Azure SQL without provisioning a separate credential. Bundled ODBC driver upgraded to 18.6.2.1 We've upgraded the bundled Microsoft ODBC Driver for SQL Server from 18.5.1.1 to 18.6.2.1. You pick up the upstream fixes and TLS/cert improvements just by upgrading the wheel. No separate ODBC install step. Bug fixes worth calling out Deferred connect-attribute use-after-free. Values passed to connection attributes set before connect are now stored in member buffers, so the driver no longer reads freed memory in some attribute-set paths. Connection string parsed multiple times in the auth path. The auth code path was reparsing the connection string several times per connect. It now operates on the already-parsed parameter dictionary, which is both faster and easier to reason about. Sensitive parameters (UID, PWD, Trusted_Connection, Authentication) are sanitized through a single canonical path before the ODBC handoff. executemany type annotation regression. seq_of_parameters now uses a covariant Sequence, so passing a list of tuples (or any covariant sequence type) type-checks cleanly again. Upgrading For most users, pip install --upgrade mssql-python is all you need. Nothing in this release is intentionally breaking. If you have type stubs or mypy pins that depended on the previous invariant seq_of_parameters annotation, you can drop the workaround. Thanks Thanks to everyone who filed issues, sent repros, and reviewed PRs in this cycle. The Row indexing and connection-string parsing work came directly from user-reported scenarios. Full changelog and PR list: microsoft/mssql-python releases.217Views0likes0CommentsAnnouncing the release of Microsoft OLE DB Driver 19.4.2 for SQL Server
We're pleased to announce the general availability (GA) release of Microsoft OLE DB Driver 19.4.2 for SQL Server. This is a maintenance update to the 19.4 line that improves TLS handling, raises a long-standing connection redirection limit, refreshes the bundled authentication library, and fixes accessibility issues in the UDL dialog. Download x64 / Arm64 installer x86 installer The 64-bit MSI continues to install the appropriate binary (x64 or Arm64) automatically based on the OS platform. MSOLEDBSQL 19 installs side by side with MSOLEDBSQL 18. Prerequisite: the Microsoft Visual C++ Redistributable must be installed before running the driver installer. What's new in 19.4.2 Features added Feature Details SSL/TLS improvements Improved SSL/TLS handling for better security and performance. 10 redirects per connection The driver no longer caps connection redirections at 2, which removes a long-standing failure mode for workloads that hit redirection-heavy topologies (for example, certain Azure SQL routing scenarios). Bugs fixed Fix Details UDL accessibility defects Fixed accessibility issues in the Universal Data Link (UDL) dialog. Updated authentication library Microsoft SQL Driver Authentication library (mssql-auth.dll) updated to version 1.1.3. mssql-auth.dll is the ADAL replacement introduced in 19.4.1 and is installed as part of the driver setup. Supported languages 19.4.2 is available in: Chinese (Simplified), Chinese (Traditional), Czech, English (United States), French, German, Italian, Japanese, Korean, Polish, Portuguese (Brazil), Russian, Spanish, and Turkish. Direct per-language download links are available in the Release notes and the Download page. Upgrading If you're on 19.4.1 or earlier in the 19.x line, an in-place upgrade is supported. As always, we recommend validating in a non-production environment first, especially if your application depends on the redirection or TLS behaviors touched in this release. Feedback Please file issues and feature requests on the Microsoft OLE DB Driver for SQL Server feedback site or via your usual support channel. Thanks to everyone who reported the UDL accessibility and redirection-limit issues that drove this release.525Views0likes0CommentsAnnouncing mssql-django 1.7.2
We're pleased to announce the release of mssql-django 1.7.2, a patch release that ships three targeted bug fixes for the Django backend for Microsoft SQL Server and Azure SQL. This release focuses on correctness: timezone-aware datetimes, QuerySet.explain() on Django 4.0+, and exception handling in a test utility. Install or upgrade from PyPI: pip install --upgrade mssql-django What's new in 1.7.2 Correct timezone handling for DATETIMEOFFSET and Now() under USE_TZ=True Two long-standing timezone issues are fixed in this release: handle_datetimeoffset now parses the timezone offset from SQL Server's binary DATETIMEOFFSET representation. Previously, values read from DATETIMEOFFSET columns could be returned without their offset, leading to naive datetimes or values converted using the wrong zone. The backend now returns properly timezone-aware datetime objects. Now() emits SYSDATETIMEOFFSET() when USE_TZ=True. When Django is configured with USE_TZ=True, the expression Now() previously compiled to SYSDATETIME(), which returns the SQL Server host's local time without offset information. On non-UTC hosts this produced timestamps that were silently shifted. With this fix, Now() compiles to SYSDATETIMEOFFSET() under USE_TZ=True and continues to compile to SYSDATETIME() when USE_TZ=False, matching Django's expectations. The release adds regression tests covering UTC, +05:30 (IST), -05:00 (EST), -09:30 (Marquesas), and +05:45 (Nepal) offsets, plus a new NowSQLTemplateTests that pins the SQL template emitted in each USE_TZ mode. QuerySet.explain() no longer raises AttributeError on Django 4.0+ In Django 4.0 the internal API for EXPLAIN plans changed: query.explain_format and query.explain_options were replaced by a single query.explain_info object. The mssql-django compiler still read the old attributes, which raised AttributeError whenever an application called .explain() on a queryset. The compiler now reads the correct attribute based on the running Django version, so .explain() works again on Django 4.0, 4.1, 4.2, 5.0, 5.1, 5.2, and 6.0. A new ExplainRegressionTests suite locks in the behavior. Test utility no longer swallows exceptions in finally A return statement inside a finally block in the JSONField support probe (_check_jsonfield_supported_sqlite()) was silently swallowing exceptions, including KeyboardInterrupt and other BaseException subclasses. The return has been removed so exceptions propagate as Python intends. Compatibility mssql-django 1.7.2 supports: Django: 3.2, 4.0, 4.1, 4.2, 5.0, 5.1, 5.2, 6.0 Python: 3.8 through 3.14 SQL Server: 2017, 2019, 2022, 2025; Azure SQL Database; Azure SQL Managed Instance ODBC Driver: 17 or 18 for SQL Server (driver 18 is the default since 1.7, with automatic fallback to 17 when 18 is not installed) No configuration changes are required to pick up the fixes in 1.7.2. Upgrade in place: pip install --upgrade mssql-django Upgrading from 1.7.1 1.7.2 is a drop-in replacement for 1.7.1. If your application: reads from DATETIMEOFFSET columns, uses django.db.models.functions.Now() with USE_TZ=True, or calls QuerySet.explain() on Django 4.0+, you will see corrected behavior after upgrading. Applications that previously worked around the timezone offset issue (for example by manually attaching tzinfo to values read from DATETIMEOFFSET columns) should review those workarounds; values returned by the ORM are now timezone-aware by default. Thank you Thanks to everyone who reported the underlying issues, contributed reproductions and test cases. Bug reports and pull requests are always welcome on GitHub. Links Source: https://github.com/microsoft/mssql-django PyPI: https://pypi.org/project/mssql-django/ Release PR: https://github.com/microsoft/mssql-django/pull/528 File an issue: https://github.com/microsoft/mssql-django/issues188Views0likes0CommentsQuery plan regressions got you down? Here's how Automatic Plan Correction can turn it around.
Automatic Plan Correction (APC) is one of the features that I find myself talking about quite a bit with customers, support engineers, and the broader SQL community. It is part of the Automatic Tuning family and has been quietly doing its job since SQL Server 2017, detecting query plan regressions and automatically forcing a previously known good plan to restore performance. But one of the questions that comes up often is: how does APC actually decide whether a regression has occurred? And how confident is it in that decision? With SQL Server 2022 CU4 and continuing into SQL Server 2025, we have made significant improvements to the statistical model that APC uses for regression detection. This blog post walks through what changed, why it matters, and how you can take advantage of it. โ๏ธ Two Ways to Detect a Regression APC supports two statistical models for determining whether a query plan has regressed. Both analyze execution statistics captured by Query Store (such as CPU time) to compare the performance of a current plan against a previously known good plan. The original model: sigma-based comparison The original regression detection model uses a sigma-based comparison (commonly associated with the "three-sigma rule"). It computes whether the difference in average CPU time between the current plan and the last known good plan exceeds a threshold of 3 standard deviations. This approach works well when execution times follow a normal distribution with consistent variance. However, we found some limitations with this approach over time: High variance can mask regressions. If CPU times vary widely for a given plan (which is common in real workloads), the standard deviation becomes large. A regression where the mean CPU time doubles might still fall within the 3-sigma band, causing APC to miss it. It assumes equal variance. The model treats the variance of both the current and baseline plan populations as comparable. When they differ significantly (for example, the regressed plan has highly variable execution times while the good plan was stable), the comparison loses precision. It requires more executions. The model needs at least 15 executions of the current plan before it makes a determination. ๐ The newer model: Welch's t-test The newer regression detection model uses the Welch's t-test, a well-established statistical hypothesis test designed specifically for comparing two populations that may have unequal variances and unequal sample sizes. If you are not familiar with the Welch's t-test, you can think of it as a more robust way to answer the question: "are these two sets of numbers actually different, or is the difference just noise?" Key improvements over the original model: Better accuracy with high-variance workloads. The Welch's t-test explicitly accounts for different variances between the current plan and the baseline plan. It won't be fooled by a plan that sometimes runs fast and sometimes runs very slow. It can still detect that the distribution has shifted unfavorably. Faster reaction time. APC can begin evaluating a plan after as few as 3 executions of the new plan, compared to 15 with the original model. When the performance difference is statistically significant, APC can detect and correct a regression much sooner. Adaptive sample sizing. If the initial sample of 3 executions produces an "uncertain" result, APC doesn't give up. It progressively increases the number of executions required before rechecking, until enough execution statistics have been gathered to make a confident determination. Multiple checks before final determination. The Welch's t-test model performs more than one check over the lifecycle of a potential regression. It re-evaluates as more data arrives, reducing the chance of both false positives and false negatives. With the Welch's t-test model, we have significantly improved both the accuracy of regression detection and the reaction time that APC takes with correcting a regression. ๐งญ Enabling the Welch's t-test model The Welch's t-test model is the default regression detection model in: Azure SQL Database, SQL Database in Microsoft Fabric, Azure SQL Managed Instance (enabled by default, no action required) SQL Server 2025 (enabled by default, no action required) For SQL Server 2022, enable it with trace flag 12618 (available starting with CU4): -- Enable globally (startup trace flag) DBCC TRACEON (12618, -1); -- Or add as a startup parameter: -T12618 The original sigma-based model remains as a fallback and is used when trace flag 12618 is not enabled on SQL Server 2022 CU4+. As always, we strongly recommend applying the latest Cumulative Updates for SQL Server. ๐งช Handling long-running and timed-out queries Both regression detection models share a common bias that I want to call out: APC checks are triggered after a certain number of query executions complete. This means APC inherently evaluates the fastest-completing executions first and may miss regressions where the symptom is queries running for minutes or timing out entirely. Let me paint a picture of what this looks like. Imagine a situation where the overall CPU utilization on a server goes from an average of 10% to 100% unexpectedly and you find out that there had been a plan change for a particular query. The extended events may show that the query had executed a few times quickly, say 15 executions that completed in milliseconds. However, during your analysis you notice that there were a lot of other query executions that were running longer, maybe for a few minutes. Some of those longer running queries completed successfully, but others were timing out. By the time those slow executions finish and their statistics reach Query Store, APC has already made its regression decision based on the fast executions and concluded there was no regression. Trace flag 12656 addresses this by enabling a time-based delayed recheck. When enabled, APC schedules an additional check 5 minutes after a plan change is first detected. This delayed check re-evaluates the query using execution statistics that now include the slower and timed-out executions, providing a more complete picture. -- Enable globally DBCC TRACEON (12656, -1); Like trace flag 12618, trace flag 12656 is also available starting with SQL Server 2022 CU4. Per-query timed recheck with sp_configure_automatic_tuning While trace flag 12656 applies this recheck globally, you can also enable it on a per-query basis using the sp_configure_automatic_tuning stored procedure with the FORCE_LAST_GOOD_PLAN_EXTENDED_CHECK option. This is especially useful in Azure SQL Database, SQL Database in Microsoft Fabric, and Azure SQL Managed Instance where the global trace flag is not available. It provides the same 5-minute delayed recheck that trace flag 12656 enables, but scoped to only the queries you choose: -- Enable timed recheck for a specific query EXEC sp_configure_automatic_tuning @option = 'FORCE_LAST_GOOD_PLAN_EXTENDED_CHECK', @option_value = 'ON', @type = 'QUERY', @type_value = <query_id>; -- Disable timed recheck for a specific query EXEC sp_configure_automatic_tuning @option = 'FORCE_LAST_GOOD_PLAN_EXTENDED_CHECK', @option_value = 'OFF', @type = 'QUERY', @type_value = <query_id>; This allows you to target specific queries that are known to have long-running or timeout-prone execution patterns without imposing the overhead of timed rechecks on every query in the database. The following table summarizes the scope differences: Method Scope Where available Trace flag 12656 All queries on the instance (global) SQL Server 2022 CU4 and later versions (including SQL Server 2025 and later versions) sp_configure_automatic_tuning FORCE_LAST_GOOD_PLAN_EXTENDED_CHECK Individual queries (per-query) SQL Server 2022 CU4 and later versions, SQL Server 2025, Azure SQL Database, SQL Database in Microsoft Fabric, and Azure SQL Managed Instance ๐ Monitoring APC decisions The illustration below can be used as a mental map of all of the phases that the automatic plan correction feature takes which can be monitored. sys.dm_db_tuning_recommendations The sys.dm_db_tuning_recommendations DMV can be used to see any actions that APC has taken if it is enabled and will also be populated if the feature is disabled, showing the action that it would have taken if it were enabled. The result set is in JSON format, so a query similar to the one below can be used to parse the output: SELECT JSON_VALUE([state], '$.currentValue') AS [state], script = JSON_VALUE(details, '$.implementationDetails.script'), planForceDetails.* FROM sys.dm_db_tuning_recommendations CROSS APPLY OPENJSON(Details, '$.planForceDetails') WITH ( [query_id] int '$.queryId', regressedPlanId int '$.regressedPlanId', recommendedPlanId int '$.recommendedPlanId', regressedPlanErrorCount int, recommendedPlanErrorCount int, regressedPlanExecutionCount int, regressedPlanCpuTimeAverage float, recommendedPlanExecutionCount int, recommendedPlanCpuTimeAverage float ) AS planForceDetails; โ ๏ธ Note: Data in sys.dm_db_tuning_recommendations is not persisted across Database Engine restarts. ๐ Extended events for deeper analysis It may also be a good idea to capture some of the APC extended events for additional insight and analysis. For general APC observability, the key events are: Extended event When it fires automatic_tuning_plan_regression_detection_check_completed APC finishes evaluating a plan for regression. Shows whether a regression was detected and corrected. automatic_tuning_plan_regression_verification_check_completed APC finishes validating a previously forced plan. automatic_tuning_check_abandoned APC abandons a check (for example, only one plan exists). automatic_tuning_recommendation_expired APC backs off from a forced plan that isn't helping. automatic_tuning_diagnostics Periodic health summary with check counts, detection counts, and correction counts. For analyzing the Welch's t-test model specifically, there is a dedicated event (not currently available for Azure SQL Database and SQL Database in Microsoft Fabric): Extended event When it fires automatic_tuning_wtest_details Fires during the Welch's t-test evaluation with detailed statistical information about the test. โ ๏ธ Note: The automatic_tuning_wtest_details event can be chattier than the other events. It is one way to validate the effects of having trace flag 12618 enabled if you are interested in comparing results in a workload between the old and new regression detection models, but consider the overhead before enabling it in production. Additionally, this event is not available in database-scoped sessions in Azure SQL Database and SQL Database in Microsoft Fabric. Here is a sample script to create a session that captures the key events: CREATE EVENT SESSION [APC_Welch_Monitor] ON SERVER ADD EVENT qds.automatic_tuning_plan_regression_detection_check_completed ( ACTION (sqlserver.database_id, sqlserver.database_name) ), ADD EVENT qds.automatic_tuning_plan_regression_verification_check_completed ( ACTION (sqlserver.database_id, sqlserver.database_name) ), ADD EVENT qds.automatic_tuning_wtest_details ( ACTION (sqlserver.database_id, sqlserver.database_name) ), ADD EVENT qds.automatic_tuning_diagnostics ( ACTION (sqlserver.database_id, sqlserver.database_name) ) ADD TARGET package0.event_file ( SET filename = N'APC_Welch_Monitor.xel', max_file_size = 50, max_rollover_files = 5 ) WITH ( MAX_MEMORY = 4096 KB, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS, MAX_DISPATCH_LATENCY = 5 SECONDS, STARTUP_STATE = OFF ); GO ALTER EVENT SESSION [APC_Welch_Monitor] ON SERVER STATE = START; ๐ Summary The table below provides a quick comparison between the two regression detection models. If you are on SQL Server 2022, I would encourage you to try trace flag 12618 and see how it improves APC's responsiveness for your workloads. If you are on SQL Server 2025 or Azure SQL Database SQL Database in Microsoft Fabric, or Azure SQL Managed Instance, the Welch's t-test model is already active by default. Regression detection models Aspect Original model (sigma-based) Welch's t-test model Statistical method 3-sigma threshold on mean CPU difference Welch's t-test (unequal variance t-test) Handles unequal variance No (assumes similar variance) Yes (explicitly models different variances) Min executions to evaluate 15 (current plan) As few as 3 (current plan), adapts exponentially Adaptive sample sizing No Yes (progressively increases required executions on uncertain results) Multiple checks Single check Multiple re-evaluations as data accumulates Default in Azure SQL DB, SQL Database in Microsoft Fabric, Azure SQL Managed Instance No (fallback) Yes Enable on SQL Server Default on SQL Server 2022 Default on SQL Server 2025; trace flag 12618 required for SQL Server 2022 CU4+ As we continue to make Automatic Plan Correction more reliable and more robust, I hope you find this blog helpful. We are always looking to hear from the community, so please continue to share your feedback and experiences at https://aka.ms/sqlfeedback. ๐ Learn More Automatic tuning sys.dm_db_tuning_recommendations Query Store overview1.1KViews5likes0CommentsMicrosoft ODBC Driver 17.11.1 for SQL Server Released
We are pleased to announce the general availability of Microsoft ODBC Driver 17.11.1 for SQL Server, released on April 30, 2026. This servicing update delivers important bug fixes and expands Linux platform support. Key Highlights Stability and correctness fixes for parameter array processing, including accurate updates to SQL_ATTR_PARAMS_PROCESSED_PTR and improved row counting when SQL_PARAM_IGNORE is used in parameter arrays. Fixed a connection error that could occur when processing Data Classification metadata in ODBC asynchronous mode. Updated RPM packaging rules to allow installation of multiple driver versions side by side. Corrected XA recovery to ensure proper computation of transaction IDs and recovery of missing transactions. Debian package installation now honors license acceptance for successful completion. New Platform Support Platform Versions macOS 14, 15, 26 Debian 13 Red Hat Enterprise Linux 10 Oracle Linux 9, 10 SUSE Linux Enterprise Server 16 Ubuntu 24.04, 25.10 Alpine Linux 3.21, 3.22, 3.23 Download The driver is available for download from the Microsoft ODBC Driver for SQL Server documentation page. Linux Installation Install or update using your distribution's package manager: Debian/Ubuntu: sudo apt-get update sudo apt-get install msodbcsql17 Red Hat/Oracle Linux: sudo yum install msodbcsql17 SUSE: sudo zypper install msodbcsql17 Alpine: sudo apk add msodbcsql17 Feedback We welcome your feedback. Please report issues on the SQL Server feedback site or open an issue on the ODBC Driver GitHub repository.605Views0likes2Commentsgo-mssqldb v1.10.0: Better Reliability, Developer Experience, and Standards Compliance
We're excited to announce the release of go-mssqldb v1.10.0, the official Microsoft Go driver for SQL Server and Azure SQL Database. This release brings significant reliability improvements, better standards compliance, and a smoother developer onboarding experience. Highlights Detect Server-Aborted Transactions (XACT_ABORT) One of the most impactful fixes in this release addresses a subtle but dangerous bug: when SQL Server aborts a transaction due to XACT_ABORT ON, the driver now correctly detects this state. Previously, a silently aborted transaction could lead to subsequent statements being auto-committed outside the intended transaction boundary, potentially causing data integrity issues. The driver now returns a clear error when you attempt to use a connection whose transaction was server-aborted. (#370) Implement driver.DriverContext Interface The driver now implements Go's driver.DriverContext interface, enabling sql.OpenDB-style usage and better integration with connection pool configuration via sql.DB.SetConnMaxLifetime, SetMaxOpenConns, etc. This brings the driver in line with modern Go database/sql conventions. (#365) Surface Errors from Rows.Close() Previously, server errors that occurred during the token drain phase of Rows.Close() were silently swallowed. Now these errors are properly surfaced to callers, making it much easier to diagnose issues like permission errors or constraint violations that manifest during result set cleanup. (#361) Nullable Civil Types for Date/Time Parameters New nullable types (civil.NullDate, civil.NullTime, civil.NullDateTime) allow you to pass nullable date/time parameters without resorting to *time.Time or raw interface{} values. These integrate cleanly with the database/sql scanner and valuer interfaces. (#325) DevContainer for Instant Development Getting started with go-mssqldb development is now as simple as opening the repo in VS Code or GitHub Codespaces. The new devcontainer configuration includes a SQL Server instance, pre-configured environment variables, and all required tooling. (#317) All Changes Features Add devcontainer for VS Code and GitHub Codespaces (#317) Add FailoverPartnerSPN connection string parameter (#327) Add NewConnectorWithProcessQueryText for mssql driver compatibility (#341) Add nullable civil types for date/time parameters (#325) Bug Fixes Allow named pipe protocol support for ARM64 Windows (#232) Detect server-aborted transactions to prevent silent auto-commit with XACT_ABORT (#370) Expose TrustServerCertificate in msdsn.Config and URL round-trip (#312) Handle COLINFO and TABNAME TDS tokens returned by tables with triggers (#343) Implement driver.DriverContext interface (#365) Make readCancelConfirmation respect context cancellation (#359) Return interface{} scanType for sql_variant instead of nil (#362) Sanitize credentials from connection string parsing errors (#319) Surface server errors from Rows.Close() during token drain (#361) Upgrade go get github.com/microsoft/go-mssqldb@v1.10.0 This release requires Go 1.21+ and is fully compatible with SQL Server 2012 through 2022 and Azure SQL Database. Contributing We welcome contributions! The new devcontainer makes it easier than ever to get started. Open the repo in VS Code, reopen in the container, and you'll have a full development environment with SQL Server ready to go. GitHub Repository Documentation Report Issues179Views0likes0Comments