• 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 as STARTED 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
    
    sql server alter endpoint state

    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.

    restart sql server service example

    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

    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 variables

    1. List All Environment Variables

    To view all environment variables and their current values, use the Get-ChildItem cmdlet with the Env: drive. Alternatively, you can use its shorter alias gci:

    # List all environment variables
    Get-ChildItem Env:
    
    # Alt cmdlet
    gci Env:
    PowerShell 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
    
    PowerShell Show Environment Variable Value

    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"
    
    PowerShell Set Environment Variable

    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 Sessions

    Exercise 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;
    
    check running spids sql server

    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>
    
    kill spid sql

    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
    
    kill all spids sql

    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 in sp_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.