-
Troubleshooting Database Mirroring Issues in SQL Server
This article contains various ways for resolving database Mirroring issues in SQL Server, guiding you through the troubleshooting process.
Maintaining high availability and data integrity in a SQL Server environment is one of the main priorities as a SQL DBA. One issue we may encounter is Mirrored databases being left in a Disconnected or In Recovery state, or it might be that your Secondary server is falling behind becoming latent with the Principal Mirror.
MSSQL Database Mirroring Issues
Imagine a scenario where a secondary instance of SQL Server is abruptly terminated due to high CPU usage, and upon restart, all Mirrored Databases are found to be in a Disconnected or In Recovery state. You may find error messages in the SQL Server log that further compounds the issue.
This issue can also happen on a Mirrored SQL Server at random for other reasons such as an unstable period on the network, or an interruption to the SQL Service on the Secondary. When we have issues with Mirroring you might see latency between the Principal Mirror and Secondary continuing to grow. Below in this post we’ll share methods of how to resolve Database Mirroring issues, first by restarting the SQL Server Database Mirroring Endpoints, then proceeding to final measures for resolving.
Resolving Mirroring Issues in SQL Server
Method 1: Pause/Resume Database Mirroring Endpoints
The SQL commands below might be particularly useful if there’s only a few disconnected databases, not all. These commands pause & resume the Mirroring session for a database:
-- Suspend Mirorring on Database ALTER DATABASE <database-name> SET PARTNER SUSPEND; -- Resume Mirroring on Database ALTER DATABASE <Database Name> SET PARTNER RESUME
Check out Microsoft Docs on Pausing & Resuming a Database Mirroring Session for more info on this part.
Method 2: Restart Database Mirroring Endpoints
Recycling the Database Mirroring Endpoints in SQL Server would likely be the next thing would I try run to attempt to resolve issues with Database Mirroring.
The first command below retrieves information on the SQL Server Mirroring Endpoint, which is required for a Mirroring setup. With this we can check the state of the endpoint, if the
Mirroring_State_Desc
column below is showing asSTARTED
it’s at least displaying as healthy.-- Get SQL Endpoint Info -- Includes mirroring_endpoint state & port SELECT e.name AS Endpoint_Name, e.state_desc AS Endpoint_State, e.type AS Endpoint_Type, e.type_desc AS Endpoint_Type_Description, d.state AS Mirroring_State, d.state_desc AS Mirroring_State_Desc, tcp.port AS Port_Number, d.is_encryption_enabled AS Encryption_Enabled, d.encryption_algorithm_desc AS Encryption_Algorithm_Desc, d.certificate_id AS Certificate_Id FROM sys.endpoints e JOIN sys.database_mirroring_endpoints d ON e.endpoint_id = d.endpoint_id JOIN sys.tcp_endpoints tcp ON e.endpoint_id = tcp.endpoint_id; -- Stop the Database Mirroring Endpoint ALTER ENDPOINT <Endpoint Name> STATE=STOPPED -- Start the Database Mirroring Endpoint ALTER ENDPOINT <Endpoint Name> STATE=STARTED
If communication between the endpoints doesn’t restart, we could try test connectivity to and from the Principal Mirror server and Secondary server. We can test network connectivity to a remote server using PowerShell – The Mirroring Port Number returned in the query above, as well as testing SQL Server (1433 default port) will need to be open.
If Mirroring is still not working after Stopping/Restarting the Mirroring Endpoint, lets continue on to the next steps in this post.
Method 3: Restart SQL Services on Secondary
We can try restart the SQL Services on the Secondary Mirror server, which will not affect the Live Service. Alternatively, you can also try reboot the Secondary Mirror host.
Method 4: Reconfigure Mirroring
If you are still with me, here till the end, we’ll need to reconfiguring Database Mirroring for each of the problem databases. Re-add each database to Mirroring, which is commonly done with a Full Backup / Transaction Log Database Restore during setup. I wish you luck and hope your databases are very big! Sometimes this might take a day to resolve.
Still Having Issues?
1. If you’re unable to re-configure Mirroring and get errors while Adding a Database to Mirroring, that’s probably narrowing down the issue. Check networking is good and review error messages thoroughly.
2. If this is a frequent issue within your environment and you’re having to resolve Mirroring issues, you should really take action and start a documented investigation. Submit a case with Microsoft, ensure you’re on the latest patch level for OS & SQL Server, and review all log files.
-
What’s New in SQL Server 2025
Microsoft announced SQL Server 2025 at Microsoft Ignite, with major new features focused on AI and integrating Azure SQL DB capabilities into on-premises servers.
Check out this Microsoft Announcement post for more information: Announcing Microsoft SQL Server 2025: Enterprise AI-ready database from ground to cloud
Key Features
– AI Integration: Built-in AI simplifies development with vector search and Retrieval-Augmented Generation (RAG) patterns, leveraging familiar T-SQL syntax.
– Enterprise AI Applications: Features a native vector store with DiskANN technology, semantic search, and AI model management via REST interfaces.
– Developer Productivity: Enhanced with REST API support, GraphQL, low-code tools, and native JSON for dynamic application development.
– Performance & Security: Improvements include query optimization, real-time change streaming, and advanced authentication with Azure Arc.
– Microsoft Fabric & Azure Arc: Streamlined data replication, real-time analytics, and simplified licensing for hybrid environments.My Thoughts
Well, none so far! I haven’t had a proper dig of what all the above really means. One of my first thoughts were that it could quickly eliminate some tools like SQL Toolbelt, and we might see our first SQL Server backed by GPU?
No doubt given some time, wait for the release and for things to bake, I’ll see it in the real-world work environment. I will of course keep following the latest information and blogs on our new SQL Server version, 17.0.x!
Early Preview SQL Server 2025 Release
SQL Server 2025 is now in preview, you can sign up for early adoption here.
-
Time To Revive This Blog
As per title, I’m keen to revive this blog here at https://peter-whyte.com. I haven’t been publishing regularly for over a year, and it’s been many years since I changed the theme/design.
So here we go, a new theme is in-place, updates are underway to improve the overall design, but most importantly I’ll be publishing new technical blog posts as a priority going forward.
This time, I also have a new approach to my writing. I have always kept things very much to the point, keep it as straight-forward as possible so readers can get the information they need quickly. No silly chats on what my feelings on the today included in any posts. Now, I intend to include my personality. I now intend on sharing my opinions!
My Thoughts Today
My current goals for this blog are as described above. Give things another fresh look and post better blog posts, consistently. This is the same approach I have with my other websites/ideas.
This blog used to get 10k+ visitors each month, and we’re currently at 1-2k p/m. This is not a metric I follow much, however going forward I will be keeping track of as I reach near future blogging goals. When we’re hitting the same numbers as before I will likely enable display Ads. I had this before and was earning around $100 per month, at peak.
Another thing on my mind is my older posts on here. I will likely disable comments on the posts that still have that enabled. Sometimes I get a random genuine comment, and it might take a month for me to see it. Since I’m back in action I’ll see comments coming through and take action, particularly when someone is posting a correction or additional advice.
That’s me for now. I hope you enjoy this blog, and much more from this point and beyond!
-
How to Set Environment Variables in PowerShell
Environment variables store key information on your system that programs can use to influence their behavior. For example, the AWS CLI uses the
AWS_REGION
variable to determine the region for API requests.This guide will cover:
– Listing all environment variables
– Retrieving the value of a specific environment variable
– Setting or updating environment variables1. List All Environment Variables
To view all environment variables and their current values, use the
Get-ChildItem
cmdlet with theEnv:
drive. Alternatively, you can use its shorter aliasgci
:# List all environment variables Get-ChildItem Env: # Alt cmdlet gci Env:
Both commands will display a list of environment variables along with their values.
2. Get the Value of a Specific Environment Variable
To return the value of a specific environment variable, such as
AWS_DEFAULT_REGION
, you can use one of these methods:# Get the value of the aws_default_region environment variable gci Env:\AWS_DEFAULT_REGION # Do the same but alt (easier) syntax $env:AWS_DEFAULT_REGION
Both commands will output the value of the
AWS_DEFAULT_REGION
variable if it is set.3. Set or Update an Environment Variable
To set or update an environment variable, assign a new value to it using the
$env:
syntax:# Set the AWS Default Region Environment Variable $env:AWS_DEFAULT_REGION="eu-west-2"
Important Notes:
– This change applies only to the current PowerShell session.
– To make the change permanent, you need to update the system or user environment variables in the Windows environment settings or use registry editing scripts.For example, setting a permanent environment variable using PowerShell might involve modifying the registry:
[System.Environment]::SetEnvironmentVariable("AWS_DEFAULT_REGION", "eu-west-2", "User")
This approach ensures that the variable is available in future sessions.
-
How to Kill SPIDs in SQL Server
In SQL Server, Session Process IDs (SPIDs) play a crucial role in identifying and managing SQL connections. The KILL (SPID) command serves as a tool for terminating troublesome sessions. This blog post provides an overview of the KILL command and its practical applications.
The following is included in this one:
> Reviewing SQL SPIDs to Kill
> Killing SQL Server Processes (SPIDs)
> Killing All SPIDs Connected to a Database
> Added Notes for Killing SQL SessionsExercise caution when using KILL SPID – It should not be a frequent task for DBA’s to be killing SPIDs. We need to resolve the problem query, for example by optimizing the SQL query code, or adding an index to help speed things along.
You might need to kill a SPID for various reasons. It could be due to a long-running query that is starting to consume too much disk space, or a blocking query that is breaking an application. Identifying the problem query and being confident about it is the harder part.
First in this article we will be reviewing currently running SPIDs on a SQL Server, and then showing some examples of killing SPIDs.
Reviewing SQL SPIDs to Kill
There are many ways to show running queries with SPID info in SQL Server. This includes querying system DMVs, checking SSMS Activity Monitor, SP_Who2 and more. Check out my other blog post for more information on ways to check active SQL queries.
Below is a simple script that queries SQL DMVs to show current SQL sessions:
-- Show current sessions SELECT s.host_name, s.program_name, r.blocking_session_id 'Blk by', Coalesce(Quotename(Db_name(st.dbid)) + N'.' + Quotename(Object_schema_name(st.objectid,st.dbid)) + N'.' + Quotename(Object_name(st.objectid,st.dbid)), '') AS command_text, s.session_id, r.cpu_time, r.logical_reads, r.reads, r.status, r.wait_type, wait_resource, r.wait_time / (1000.0) 'Wait (in sec)', r.writes, r.total_elapsed_time / (1000.0) 'Elapsed (in sec)', SUBSTRING(st.TEXT,(r.statement_start_offset / 2) + 1, ((CASE r.statement_end_offset WHEN -1 THEN Datalength(st.TEXT) ELSE r.statement_end_offset END - r.statement_start_offset) / 2) + 1) AS statement_text, r.command, s.login_name, s.last_request_end_time, s.login_time, r.open_transaction_count FROM sys.dm_exec_sessions AS s JOIN sys.dm_exec_requests AS r ON r.session_id = s.session_id CROSS APPLY sys.Dm_exec_sql_text(r.sql_handle) AS st ORDER BY r.cpu_time DESC;
When we review running SPIDs, we should understand, typically SPIDs 1 to 50 are designated for SQL Server’s internal processes, with user processes beginning from SPID 51 onwards. As additional tasks are undertaken within your environment, you may observe more than just 1-50 being used by the SQL internal systems. An error message should prevent you from killing core SQL system SPIDs anyway.
Usually we’re looking for blocking or long-running queries, more commonly those are the problem sessions.
Note down the SPID number, and move onto the next step when we’re confident we want that session to end.
Killing a SQL Server Process (SPID)
To kill a SQL SPID, insert the SPID number after the word KILL, then run the command:
-- kill a sql session (SPID) KILL <SPID>
When the kill command has been executed, the session should end, or try to and start rolling back.
We can monitor the progress of a terminated SPID rollback by running “
KILL WITH STATUSONLY
“. This SQL command generates a progress report for rolling back session IDs or Unit of Work (UOW) after a “KILL session ID|UOW” statement has been run. The output report includes rollback completion percentage and estimated time remaining, however it does not always return a value.When a rollback is happening and it’s causing issues with your application or system, you might have to just wait it out. However, that might not be an easy option…. I’ll never forget hearing about this 2 month rollback of a killed SPID! Be prepared for an alternative recovery plan if things are really that bad.
Killing All SPIDs on a Database
DBA’s often encounter scenarios where they need to terminate all user sessions/processes for a specific database. This may be necessary during maintenance tasks, e.g. building/migrating a new SQL Server, or perhaps for when trying to drop a database.
I’ve set this script to print results instead of execute for safety. You can get it going by uncommenting the EXEC command line.
--Kill all user SPIDs USE master GO DECLARE @kill VARCHAR(8000) = ''; SELECT @kill = @kill + 'kill ' + CONVERT(VARCHAR(5), spid) + ';' FROM master..sysprocesses WHERE dbid = db_id('DATABASE123') -- Change Database Name here PRINT @kill -- EXEC(@kill) --uncomment when ready
Added Notes for Killing SQL Sessions
The
KILL SPID
command can be used to resolve blocking scenarios by terminating the offending session, restoring system functionality. Or, you may be facing a runaway SPID that has been executing a very long time without yielding any progress for an extended period. There’s various reasons why you might need to kill a SQL session, however it should not be something you need to do often as I’ve described in this post.It is important to note that killing a SPID can cause rollbacks, which can take longer than expected and continue to block other queries. You can use the KILL command with the
STATUSONLY
option, or query system DMVs to check the status of a killed query. In some cases, a lead blocking SPID may not appear insp_whoisactive
results, in which case you can use Activity Monitor to find the correct SPID to kill.Killing all sessions on a database might be necessary during maintenance tasks, for example dropping a non-Production database.
Hope this blog post was a useful one for you! Feel free to check out my SQL Server Processes tag blog for some more related info.