Quick Answer
DBMIRROR_SEND occurs when SQL Server's database mirroring cannot send data to the mirror server due to network congestion or the mirror server being unable to keep up with the principal's transaction rate. This indicates throughput bottlenecks in the mirroring transport layer and can lead to transaction log growth on the principal server.
Root Cause Analysis
DBMIRROR_SEND waits occur in the database mirroring send thread when the network transport layer's send buffers become full. The mirroring architecture uses dedicated threads for sending log records to the mirror server, and these threads must wait when the underlying TCP send buffers reach capacity.
The wait happens in the mirroring transport manager when it attempts to queue log records for transmission but finds the network layer cannot accept more data. This typically results from one of three conditions: network bandwidth limitations, high network latency causing TCP window scaling issues, or the mirror server being unable to process incoming log records fast enough due to disk I/O bottlenecks.
In synchronous mirroring mode, this wait directly impacts transaction commit times because the principal must wait for acknowledgment from the mirror before committing transactions. In asynchronous mode, log records are sent without waiting for acknowledgment, so the send itself is not blocked. However, the transaction log on the principal cannot be truncated until the mirror confirms it has hardened the log records, so sustained send bottlenecks in asynchronous mode manifest as transaction log growth on the principal server.
SQL Server 2012 and later versions improved the mirroring transport layer to use larger send buffers and better buffer management, reducing the frequency of these waits compared to SQL Server 2008 R2 and earlier versions. However, the fundamental bottleneck points remain the same across all versions that support database mirroring.
The wait occurs specifically in the database mirroring worker threads, not in user connection threads, which means high DBMIRROR_SEND waits won't directly show up in application performance but will manifest as transaction log growth and potential failover delays.
AutoDBA checks Database mirroring configuration, network timeout settings, and transaction log growth monitoring across your entire SQL Server instance in 60 seconds. Download the free diagnostic script and see what else needs attention.
Diagnostic Queries
-- Check current database mirroring status and performance counters
SELECT
d.name AS database_name,
m.mirroring_role_desc,
m.mirroring_state_desc,
m.mirroring_safety_level_desc,
m.mirroring_witness_name,
m.mirroring_connection_timeout
FROM sys.database_mirroring m
INNER JOIN sys.databases d ON m.database_id = d.database_id
WHERE m.mirroring_guid IS NOT NULL;
-- Examine wait statistics specifically for database mirroring
SELECT
wait_type,
waiting_tasks_count,
wait_time_ms,
max_wait_time_ms,
signal_wait_time_ms,
wait_time_ms / NULLIF(waiting_tasks_count, 0) as avg_wait_time_ms
FROM sys.dm_os_wait_stats
WHERE wait_type LIKE 'DBMIRROR%'
ORDER BY wait_time_ms DESC;
-- Check transaction log size and growth for mirrored databases
SELECT
d.name AS database_name,
mf.name AS log_file_name,
mf.size * 8 / 1024 AS log_size_mb,
mf.growth AS growth_setting,
CASE mf.is_percent_growth
WHEN 1 THEN 'Percent'
ELSE 'MB'
END AS growth_type,
CASE
WHEN m.mirroring_state = 4 THEN 'SYNCHRONIZED'
WHEN m.mirroring_state = 3 THEN 'SYNCHRONIZING'
WHEN m.mirroring_state = 2 THEN 'DISCONNECTED'
WHEN m.mirroring_state = 1 THEN 'SUSPENDED'
ELSE 'UNKNOWN'
END AS mirror_state
FROM sys.master_files mf
INNER JOIN sys.databases d ON mf.database_id = d.database_id
INNER JOIN sys.database_mirroring m ON d.database_id = m.database_id
WHERE mf.type = 1 -- Log files only
AND m.mirroring_guid IS NOT NULL;
-- Monitor database mirroring performance counters
SELECT
object_name,
counter_name,
instance_name,
cntr_value
FROM sys.dm_os_performance_counters
WHERE object_name LIKE '%Database Mirroring%'
AND counter_name IN ('Bytes Sent/sec', 'Log Send Queue KB', 'Transaction Delay', 'Send/Receive Ack Time')
ORDER BY object_name, counter_name, instance_name;
-- Check for network-related issues and connection timeouts
SELECT
d.name AS database_name,
m.mirroring_partner_name,
m.mirroring_partner_instance,
m.mirroring_connection_timeout,
m.mirroring_redo_queue_type,
DATEDIFF(second, m.mirroring_state_last_change, GETDATE()) AS seconds_since_last_state_change
FROM sys.database_mirroring m
INNER JOIN sys.databases d ON m.database_id = d.database_id
WHERE m.mirroring_guid IS NOT NULL;
Fix Scripts
Increase Database Mirroring Timeout Values Extends connection timeout to handle temporary network congestion. Test thoroughly as this affects failover detection time.
-- Increase connection timeout for database mirroring
-- WARNING: This increases time to detect partner failures
USE [YourMirroredDatabase];
ALTER DATABASE [YourMirroredDatabase]
SET PARTNER TIMEOUT = 20; -- Default is 10 seconds
GO
Optimize Transaction Log Management Ensures transaction log doesn't grow excessively during mirroring delays. Only run during maintenance windows.
-- Set appropriate log file initial size and growth
-- Run on principal server during maintenance window
USE [master];
GO
ALTER DATABASE [YourMirroredDatabase]
MODIFY FILE (
NAME = 'YourDatabase_Log',
SIZE = 1024MB, -- Set based on typical log usage
FILEGROWTH = 512MB -- Use fixed MB growth, not percentage
);
GO
Temporarily Switch to Asynchronous Mode Reduces transaction commit delays when network performance is degraded. Plan for manual failover if needed.
-- Temporarily switch to high-performance mode (asynchronous)
-- WARNING: This allows potential data loss during failover
USE [YourMirroredDatabase];
GO
ALTER DATABASE [YourMirroredDatabase]
SET PARTNER SAFETY OFF;
GO
-- Remember to switch back to SAFETY FULL when network issues resolve
Reset Wait Statistics for Clean Monitoring Clears historical wait data to monitor current performance. Only run when you want to reset monitoring baseline.
-- Clear wait statistics to monitor current performance
-- WARNING: This removes all historical wait statistics
DBCC SQLPERF('sys.dm_os_wait_stats', CLEAR);
GO
AutoDBA generates fix scripts like these automatically, with impact estimates and rollback SQL included.
Prevention
Configure database mirroring with appropriate timeout values based on your network characteristics. Set connection timeout to at least 3-4 times your typical network round-trip time to avoid false disconnections during temporary congestion.
Size transaction log files appropriately with fixed MB growth settings rather than percentage growth. Monitor log file sizes regularly and set up alerts when log usage exceeds 70% of allocated space to prevent emergency log growth during mirroring delays.
Implement network monitoring between mirroring partners to detect bandwidth utilization and latency spikes before they impact mirroring performance. Use dedicated network connections for mirroring traffic when possible, especially in high-transaction environments.
Configure SQL Server's network packet size parameter to optimize for your network infrastructure. For high-latency networks, increase the packet size to 8192 bytes to reduce the number of round trips required for large log record transmissions.
Set up automated alerts on the "Log Send Queue KB" performance counter to detect when the principal server cannot send log records fast enough. Values consistently above 10MB indicate sustained mirroring throughput issues that require intervention.
Consider implementing compression at the network level or using SQL Server's backup compression features if your mirroring partners support it, as this can reduce the amount of data transmitted over potentially constrained network connections.
Need hands-on help?
Dealing with persistent dbmirror_send issues across your environment? Samix Technology provides hands-on SQL Server performance consulting with 15+ years of production DBA experience.