sqlserver
73 TopicsAnnouncing 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/issues11Views0likes0CommentsQuery 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 overview779Views4likes0CommentsMicrosoft 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.425Views0likes2Commentsgo-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 Issues138Views0likes0CommentsAnnouncing Microsoft.Data.SqlClient 6.1.5
We are pleased to announce the release of Microsoft.Data.SqlClient 6.1.5, the latest servicing update to the 6.1 line. This update focuses on connection performance, error propagation, and vector type metadata correctness. Install or update from NuGet: dotnet add package Microsoft.Data.SqlClient --version 6.1.5 Full release notes: 6.1.5 Release Notes What's in this release Faster connection opens for non-integrated authentication on native SNI A regression caused SPN (Service Principal Name) generation to run for non-integrated authentication modes, such as SQL authentication, on the native SNI path. That triggered unnecessary DNS lookups and could significantly slow down connection opens. This fix restores the expected behavior for affected .NET applications on Windows. (#3523, #3946) ExecuteScalar now propagates post-row server errors ExecuteScalar could previously hide errors when SQL Server returned row data followed by an error token. In those cases, errors such as conversion failures during WHERE clause evaluation were consumed during SqlDataReader.Close() instead of being thrown to the caller, which could leave transactions unexpectedly zombied. This fix ensures the error is surfaced correctly to application code. (#3736, #3947) Correct metadata type for vector float32 columns SqlDataReader.GetFieldType() and GetProviderSpecificFieldType() now return the correct type, SqlVector<float>, for vector float32 columns. Previously these APIs returned metadata that did not match the type-resolution behavior used by GetValue(). (#4104, #4151) Getting started If you are new to Microsoft.Data.SqlClient, check out the introduction documentation. For users of System.Data.SqlClient, please move migrate to Microsoft.Data.SqlClient now. See the porting cheat sheet. If you encounter any issues, please report them on the GitHub repository.279Views0likes0CommentsAnnouncing Microsoft Drivers 5.13.1 for PHP for SQL Server
Announcing Microsoft Drivers 5.13.1 for PHP for SQL Server We have released Microsoft Drivers 5.13.1 for PHP for SQL Server (sqlsrv and pdo_sqlsrv). This patch release addresses several important bug fixes, including a security fix for access token handling in pooled connections and multiple stability improvements. Bug Fixes Access token identity leaking across pooled connections When using access token authentication with connection pooling, connections with different tokens could share the same pool entry, causing identity cross-contamination and use-after-free. This release properly incorporates the access token into the connection pool key, ensuring connections are only reused when the token matches. (#1592, fixes #1396) Prepared statement silently failing on insert A prepared INSERT statement could silently fail when triggers or SET NOCOUNT OFF produce extra result sets, causing an implicit transaction rollback with MARS enabled. The driver now correctly handles this scenario. (#1590) Fatal error re-executing prepared statements with varying result sets Re-executing a prepared statement that returns multiple result sets with different column layouts could cause a fatal error. Metadata entries are now properly freed, and the internal vector is cleared between executions. (#1596) sqlsrv_errors() returning null after failed connection When a connection attempt failed and ODBC provided no diagnostic records, sqlsrv_errors() would return null instead of surfacing the error. Connection failures now consistently report the underlying error. (#1595) Stream becoming invalid when statement goes out of scope A binary stream could become invalid when the originating statement went out of scope, leading to undefined behavior or crashes. The driver now properly invalidates streams when their parent statement is destroyed. (#1598, fixes #1443) Installation PECL (Linux/macOS) sudo pecl install sqlsrv sudo pecl install pdo_sqlsrv Windows Download the prebuilt binaries from the GitHub Releases page and follow the loading instructions. Prerequisites ODBC Driver: Microsoft ODBC Driver 17 or 18 for SQL Server PHP: 8.3, 8.4, or 8.5 For detailed platform-specific installation steps, see the Linux and macOS installation guide. Upgrading from 5.13.0 This is a drop-in hotfix release. No API changes, no configuration changes. Update via PECL or replace the DLLs on Windows. If you are using access token authentication with connection pooling, we strongly recommend upgrading to this release. Resources GitHub Repository Official Documentation PECL sqlsrv PECL pdo_sqlsrv Release Notes (CHANGELOG) Report Issues Feedback We welcome your feedback and contributions. Please file issues, feature requests and pull requests on our GitHub Issues page.109Views0likes0CommentsAnnouncing Microsoft.Data.SqlClient 7.0.1
We are pleased to announce the release of Microsoft.Data.SqlClient 7.0.1, the first servicing update to the 7.0 line. This patch addresses several compatibility fixes reported by the community after the 7.0.0 GA release. Install or update from NuGet: dotnet add package Microsoft.Data.SqlClient --version 7.0.1 Full release notes: 7.0.1 Release Notes What's in this release SqlBulkCopy fixes for SQL Server 2016 and Azure Synapse Two separate issues affected SqlBulkCopy on older or specialized SQL Server engines: SQL Server 2016 compatibility -- SqlBulkCopy operations failed with Invalid column name 'graph_type' because the column metadata query referenced a column introduced in SQL Server 2017. The query now uses dynamic SQL so the graph_type reference is not compiled on versions that lack the column. (#3714) Azure Synapse dedicated SQL pools -- The column-list query used a variable-assignment pattern that Synapse does not support. The driver now detects Synapse (engine edition 6) and uses STRING_AGG instead, while preserving the variable-assignment fallback for SQL Server 2016 compatibility. (#4149) Vector column type metadata SqlDataReader.GetFieldType() and GetProviderSpecificFieldType() previously returned typeof(byte[]) for vector float32 columns instead of typeof(SqlVector<float>). These methods now follow the same type-determination logic as GetValue(), returning the correct vector type. (#4104) Missing System.Data.Common dependency on .NET Framework The inbox System.Data.Common assembly on .NET Framework predates APIs such as IDbColumnSchemaGenerator. Without the NuGet package dependency, consumers hit CS0012 compilation errors when using these types through Microsoft.Data.SqlClient. The package now explicitly depends on System.Data.Common v4.3.0 for .NET Framework targets. (#4063) User Agent TDS extension enabled unconditionally The Switch.Microsoft.Data.SqlClient.EnableUserAgent AppContext switch has been removed. The driver now always sends User Agent information during login. (#4124) Type forwards for extracted Azure authentication types Type forwards have been added from the core Microsoft.Data.SqlClient assembly to public types that moved to the Microsoft.Data.SqlClient.Extensions.Abstractions package in 7.0.0: SqlAuthenticationMethod, SqlAuthenticationParameters, SqlAuthenticationProvider, SqlAuthenticationProviderException, and SqlAuthenticationToken. This ensures binary compatibility for assemblies compiled against earlier versions of Microsoft.Data.SqlClient. (#4067) Community contributions Both of the SqlBulkCopy fixes in this release were driven by community contributor edwardneal: SQL Server 2016 fix -- Edward authored the original PR (#3719) that rewrote the column metadata query to use dynamic SQL, preventing the graph_type column reference from being compiled on servers that lack it. The fix was recreated on an internal branch (#4092) to enable CI pipeline testing against SQL Server 2016 and 2017. Azure Synapse fix -- Edward identified and fixed (#4176) the incompatibility with Azure Synapse dedicated SQL pools, where the variable-assignment concatenation pattern used to build the column list is not supported. His fix detects Synapse via SERVERPROPERTY('EngineEdition') and switches to STRING_AGG, while preserving the variable-assignment fallback for SQL Server 2016. He manually validated the fix against SQL Server 2016, SQL Server 2025, and an Azure Synapse dedicated SQL pool. We are grateful for Edward's continued contributions to SqlClient. Community involvement like this directly improves the experience for all SqlClient users. Getting started If you are new to Microsoft.Data.SqlClient, check out the documentation. For users of System.Data.SqlClient, see the porting cheat sheet. If you encounter any issues, please report them on the GitHub repository.588Views0likes0Commentsmssql-python 1.6: Unblocking Your Threads
The last two mssql-python releases shipped big features: Bulk Copy in 1.4 for high-throughput data loading, and Apache Arrow in 1.5 for zero-copy analytics. Version 1.6 is about what happens next: you take those features into production, scale up your thread pool, and find out where the driver was quietly holding you back. This release unblocks your threads during connection setup, fixes crashes and incorrect results in common cursor patterns, and hardens security for passwords with special characters and log file paths. pip install --upgrade mssql-python Your threads can run while connections are opening If you're running mssql-python behind Flask, FastAPI, Django, or any WSGI/ASGI server with thread-based workers, this one matters. Opening a database connection is slow. There's DNS resolution, a TCP handshake, TLS negotiation, and SQL Server authentication. In previous versions, every other Python thread in your process was frozen while that happened, because the driver held the Global Interpreter Lock (GIL) during the entire operation. One thread opening a connection meant no other thread could serve requests, process data, or do anything at all. Version 1.6 releases the GIL during connect and disconnect. Your other threads keep running while the network round-trip completes. If you have a multi-threaded web server handling concurrent requests, this removes a serialization bottleneck you may not have realized you had. The connection pool was also reworked to stay safe under this change. Previously, the pool held an internal lock while calling connect, which would have created a deadlock now that connect releases the GIL. The pool now reserves a slot first, connects outside the lock, and rolls back the reservation if the connection fails. Decimal parameters work with setinputsizes If you use cursor.setinputsizes() to declare parameter types for performance-sensitive batch inserts, you may have hit a crash when specifying SQL_DECIMAL or SQL_NUMERIC. This is fixed. Decimal values now bind correctly whether you're using execute() or executemany(): cursor.setinputsizes([ (mssql_python.SQL_WVARCHAR, 100, 0), (mssql_python.SQL_INTEGER, 0, 0), (mssql_python.SQL_DECIMAL, 18, 2), ]) cursor.executemany( "INSERT INTO Products (Name, CategoryID, Price) VALUES (?, ?, ?)", [ ("Widget", 1, Decimal("19.99")), ("Gadget", 2, Decimal("29.99")), ], ) Iterating catalog results with fetchone() If you've used cursor.tables(), cursor.columns(), or other catalog methods and tried to walk the results with fetchone(), you may have gotten incorrect data. Row tracking was broken for catalog result sets. This now works the way you'd expect: cursor.tables(tableType="TABLE") while True: row = cursor.fetchone() if row is None: break print(row.table_name) This also applies to primaryKeys(), foreignKeys(), statistics(), procedures(), and getTypeInfo(). Reusing prepared statements without reset If you call cursor.execute() with reset_cursor=False to reuse a prepared statement across calls, this no longer raises an "Invalid cursor state" error. Passwords with special characters stay masked in logs If your SQL Server password contains semicolons, braces, or other ODBC-special characters (e.g., PWD={Top;Secret}), previous versions could accidentally leak part of it in sanitized log output. The password masking logic has been rewritten to correctly handle all ODBC connection string formats. If the connection string can't be parsed at all, the entire string is now redacted rather than partially exposed. The logging system also now rejects log file paths that attempt directory traversal, preventing setup_logging(log_file_path="../../somewhere/else.log") from writing outside the intended directory. Better type checker support for executemany If your type checker flagged executemany() when you passed dictionaries as parameter rows, that warning is gone. The type annotations now correctly accept Mapping types, matching the DB API 2.0 spec for named parameters. Get started pip install --upgrade mssql-python For questions or issues, file them on GitHub or email mssql-python@microsoft.com.240Views0likes0CommentsIntroducing Pacemaker HA Agent v2 for SQL Server on Linux (In Preview)
We are excited to introduce the next generation of high availability (HA) Agent for SQL Server on Linux: Pacemaker HA Agent v2. This release is a major step forward, designed to reduce planned and unplanned failover times, compared to the previous agent, based on internal engineering improvements. Why Pacemaker Is Required for SQL Server HA on Linux For users new to Linux, it’s important to understand how high availability works on this platform. On Windows Server, Always On availability groups use an underlying Windows Server Failover Cluster (WSFC) to: Monitor node health Detect failures Orchestrate automatic failovers Always On availability groups on Linux rely on an external cluster orchestrator for health monitoring and failover coordination, with Pacemaker HA Agent being one of the cluster orchestrators, responsible for: Monitoring node and application health Coordinating failover decisions Helping mitigate split‑brain scenarios through improved write‑lease evaluation Managing resources such as availability groups and listeners The Pacemaker HA Agent is the integration layer that allows Pacemaker to understand SQL Server health and manage availability groups safely. Evolution of the SQL Server Pacemaker HA Agent With SQL Server 2025 CU3 and later, Pacemaker HA Agent v2 is available in preview for Red Hat Enterprise Linux and Ubuntu through the mssql-server-ha package. Pacemaker HA agent v2 uses a service‑based architecture. The agent runs as a dedicated system service named mssql-pcsag, which is responsible for handling SQL Server–specific high availability operations and communication with Pacemaker. You can manage mssql-pcsag service by using standard system service controls to start, restart, status and stop this service by using the operating system's service manager (for example, systemctl). # Start the mssql-pcsag service sudo systemctl start mssql-pcsag # Restart the mssql-pcsag service sudo systemctl restart mssql-pcsag # Check the status of the mssql-pcsag service sudo systemctl status mssql-pcsag # Stop the mssql-pcsag service sudo systemctl stop mssql-pcsag Limitations of Pacemaker HA Agent v1 While the original agent enabled SQL Server HA on Linux, customers running production workloads encountered several challenges: Failover delays of 30 seconds to 2 minutes during planned or unplanned events Limited health detection, missing conditions such as I/O stalls and memory pressure Rigid failover behavior, unlike the flexible policies available on Windows (WSFC) Incomplete write‑lease handling, requiring custom logic No support for TLS1.3 for Pacemaker and SQL Server communications How Pacemaker HA Agent v2 Addresses These Gaps Pacemaker HA Agent v2 is a ground‑up improvement, designed to improve the reliability characteristics of SQL Server HA on Linux. 1. Faster & Smarter Failover Decisions The new agent introduces a service‑based health monitoring architecture, moving beyond basic polling. This allows SQL Server to report detailed diagnostic signals - improving detection speed and helping reduce failover delays in supported configurations. 2. Flexible Automatic Failover Policies inspired by the WSFC health model Pacemaker HA Agent v2 supports failure‑condition levels (1–5) and health‑check timeout model aligned with those available in Always On availability groups on Windows. This provides: Fine‑grained control over failover sensitivity, allowing administrators to tune when failover should occur. Improved detection of internal SQL Server conditions, such as memory pressure, internal deadlocks, orphaned spinlocks, and other engine‑level failures. Failover decisions are now driven by detailed diagnostics from sp_server_diagnostics, enabling faster and more accurate response to unhealthy states and providing enhanced resiliency capabilities for SQL Server AG on Linux. You can configure the failure condition level and health check timeout using the following commands: -- Setting failure condition level ALTER AVAILABILITY GROUP pacemakerag SET (FAILURE_CONDITION_LEVEL = 2); -- Setting health check timeout ALTER AVAILABILITY GROUP pacemakerag SET (HEALTH_CHECK_TIMEOUT = 60000); After applying the configuration, validate the setting using the sys.availability_groups DMV: 3. Robust Write Lease Validity Handling To prevent split‑brain scenarios, SQL Server on Linux uses an external write‑lease mechanism. In v1, lease information was not fully integrated into failover decisions. In v2, the agent actively evaluates the write-lease validity, before initiating transitions. This supports controlled role changes and improved data consistency behavior during failover events, depending on cluster configuration. 4. TLS 1.3 Support Pacemaker HA agent v2 includes design updates to support TLS 1.3–based communication for health checks and failover operations, when TLS 1.3 is enabled. Supported Versions & Distributions Pacemaker HA Agent v2 supports: SQL Server 2025 CU3 or later RHEL 9 or later Ubuntu 22.04 or higher. Preview upgrade & migration guidance for non-production environments New or existing non-prod deployments running SQL Server 2025 (17.x) can migrate from Pacemaker HA Agent v1 to v2 using following approach: Drop the existing AG resource sudo pcs resource delete <NameForAGResource> This temporarily pauses AG synchronization but does not delete the availability group (AG). After the resource is recreated, Pacemaker resumes management and AG synchronization automatically. Create a new AG resource using the v2 agent (ocf:mssql:agv2) sudo pcs resource create <NameForAGResource> ocf:mssql:agv2 ag_name=<AGName> meta failure-timeout=30s promotable notify=true Validate cluster health sudo pcs status Resume normal operations References Create and Configure an Availability Group for SQL Server on Linux - SQL Server | Microsoft Learn Thank You, Engineering: David Liao Attinder Pal Singh369Views2likes3CommentsCreating a Contained Availability Group and Enabling Database Creation via CAG Listener
A Contained Availability Group (CAG) is designed to simplify high availability and disaster recovery by encapsulating system databases (master, msdb) within the availability group itself. This means that logins, jobs, credentials, and other metadata are automatically replicated across replicas, eliminating the need for manual synchronization and reducing operational complexity. Starting with SQL Server 2025 CU1, you can create or restore databases directly through the CAG listener - without connecting to the physical instance - by enabling a session context key. Why Contained AGs Matter Self-contained HA unit: Each CAG has its own copy of master and msdb, making it independent of the physical SQL instance. Simplified failover: When the AG fails over, all associated metadata moves with it, ensuring applications continue to function without manual intervention. Improved automation: Supports scenarios where direct access to the SQL instance is restricted, enabling operations through the AG listener. Enhanced security: Reduces exposure by limiting instance-level access; operations can be scoped to the AG context. Streamlined management: Eliminates the need for login and job replication scripts across replicas. Step 1: Prepare the Database for Availability Group This example uses SQL Server on Linux; however, the steps are identical for SQL Server on Windows. In this walkthrough, an existing database named CAGDB is added to a Contained Availability Group (CAG). Before adding the database to the CAG, verify that it is configured for FULL recovery mode and perform a full database backup. ALTER DATABASE CAGDB SET RECOVERY FULL; GO BACKUP DATABASE CAGDB TO DISK = N'/var/opt/mssql/backups/CAGDB.bak' WITH INIT, COMPRESSION; GO Note: On Linux, ensure that the backup target directory exists and is owned by the mssql user. sudo mkdir -p /var/opt/mssql/backups sudo chown mssql:mssql /var/opt/mssql/backups Step 2: Create the Contained Availability Group On your Linux SQL Server nodes, run: CREATE AVAILABILITY GROUP [CAGDemo] WITH ( CLUSTER_TYPE = EXTERNAL, CONTAINED ) FOR DATABASE [CAGDB] REPLICA ON N'node1' WITH ( ENDPOINT_URL = N'tcp://node1:5022', AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, FAILOVER_MODE = EXTERNAL, SEEDING_MODE = AUTOMATIC ), N'node2' WITH ( ENDPOINT_URL = N'tcp://node2:5022', AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, FAILOVER_MODE = EXTERNAL, SEEDING_MODE = AUTOMATIC ); GO #Connect to secondary replicas and join the AG: ALTER AVAILABILITY GROUP [CAGDemo] JOIN WITH (CLUSTER_TYPE = EXTERNAL); ALTER AVAILABILITY GROUP [CAGDemo] GRANT CREATE ANY DATABASE; Step 3: Configure Listener and Connect Create a listener and connect using SSMS or sqlcmd: ALTER AVAILABILITY GROUP [CAGDemo] ADD LISTENER N'CAGDemoListener' ( WITH IP ( (N'*.*.*.*', N'255.255.255.0') ), PORT = 1453 ); GO Step 4: Connect to CAGDemoListener and attempt Database Creation (Failure) When connected through the listener: CREATE DATABASE TestCAGDB; Result:\ Msg 262, Level 14, State 1: CREATE DATABASE is not allowed in this context.\ This happens because database creation is blocked by default in a contained AG session. Step 5: Enable Database Creation in CAG Session or Instance master EXEC sp_set_session_context key = N'allow_cag_create_db', @value = 1; This enables database creation for your current session. Step 6: Retry Database Creation (Success) CREATE DATABASE TestCAGDB; Result: Database created successfully within the contained AG context. Users with dbcreator role in the CAG context can perform this action. Step 7: Backup the database. ALTER DATABASE TestCAGDB SET RECOVERY FULL; BACKUP DATABASE TestCAGDB TO DISK = N'/var/opt/mssql/data/backups/TestCAGDB.bak'; Step 8: Add database to the CAG ALTER AVAILABILITY GROUP [CAGDemo] ADD DATABASE [TestCAGDB]; Optional: To automate Steps 4 - 8, you can create a stored procedure (for example: [dbo].[sp_cag_create_db]) and execute it while connected through the Contained Availability Group (CAG) listener context. CREATE OR ALTER PROCEDURE [dbo].[sp_cag_create_db] @database_name sysname, @createdb_sql NVARCHAR(MAX) = NULL AS BEGIN SET NOCOUNT ON DECLARE @fIsContainedAGSession int EXECUTE @fIsContainedAGSession = sys.sp_MSIsContainedAGSession if (@fIsContainedAGSession = 1) BEGIN DECLARE @SQL NVARCHAR(MAX); EXEC sp_set_session_context = N'allow_cag_create_db', @value = 1; IF @createdb_sql IS NULL SET @SQL = 'CREATE DATABASE ' + QUOTENAME(@database_name); ELSE SET @SQL = @createdb_sql; PRINT @SQL EXEC sp_executesql @SQL; SET @SQL = 'ALTER DATABASE ' + QUOTENAME(@database_name) + ' SET RECOVERY FULL'; PRINT @SQL EXEC sp_executesql @SQL; SET @SQL = 'BACKUP DATABASE ' + QUOTENAME(@database_name) + ' TO DISK = N''NUL'''; PRINT @SQL EXEC sp_executesql @SQL; DECLARE _Name sysname; set _Name = (SELECT name FROM sys.availability_groups ags INNER JOIN sys.dm_exec_sessions des ON ags.group_id = des.contained_availability_group_id WHERE @@SPID = des.session_id); SET @SQL = 'use master; ALTER AVAILABILITY GROUP ' + QUOTENAME(@AG_Name) + ' add DATABASE ' + QUOTENAME (@database_name) PRINT @SQL EXEC sp_executesql @SQL; EXEC sp_set_session_context key = N'allow_cag_create_db', @value = 0; END ELSE BEGIN RAISERROR('This can only be used with a contained availability group connection.', 16, 1); END END GO At a high level, this procedure simplifies database onboarding into a CAG by orchestrating the following actions as a single workflow: Creating (or restoring) the database Setting the recovery model to FULL Taking the initial backup required for availability group seeding Adding the database to the target Contained Availability Group Example: Create a database Execute the following command to create NewTestDB and add it to the target CAG. EXEC [dbo].sp_cag_create_db @database_name = [NewTestDB]; Example: Restore a database The stored procedure also supports an optional parameter, @createdb_sql, which allows you to provide a custom SQL statement to create or restore a database (for example, restoring from a backup). Once the database backup file exists and is accessible to SQL Server, you can use this parameter to perform the operation. Important: When @createdb_sql is used, the procedure executes that SQL statement directly. Ensure the SQL statement is from a secured and trusted source. DECLARE @restoreSql NVARCHAR(MAX); SET @restoreSql = N' RESTORE DATABASE AdventureWorks2022 FROM DISK = ''/var/opt/mssql/backups/AdventureWorks2022.bak'' WITH MOVE ''AdventureWorks2022'' TO ''/var/opt/mssql/data/AdventureWorks2022.mdf'', MOVE ''AdventureWorks2022_log'' TO ''/var/opt/mssql/data/AdventureWorks2022_log.ldf'', RECOVERY; '; EXEC dbo.sp_cag_create_db @database_name = N'AdventureWorks2022', @createdb_sql = @restoreSql; Conclusion Contained Availability Groups represent a major step forward in simplifying high availability for SQL Server. By encapsulating system databases within the AG context, they eliminate the complexity of synchronizing logins, jobs, and credentials across replicas. With the new capability in SQL Server 2025 CU1 to create or restore databases directly through the AG listener using sp_set_session_context, organizations can streamline automation and reduce operational overhead. References What Is a Contained Availability Group Deploy a Pacemaker Cluster for SQL Server on Linux797Views1like0Comments