监控可用性组:如何查询判断可用性组是否存在异常
我明白这种找不到问题根源的挫败感——当AG状态显示NOT_HEALTHY但常规副本查询看起来正常时,确实很头疼。下面我整理了一套分层的SQL查询方案,从核心状态到深层细节帮你定位问题:
核心综合排查查询
这个查询整合了多个关键DMV,一次性展示AG、副本、数据库的核心健康状态,帮你快速定位异常点:
SELECT ag.name AS AG_Name, ags.synchronization_health_desc, ar.replica_server_name, ar.role_desc, ars.connected_state_desc, ars.synchronization_health_desc AS Replica_Sync_Health, ars.availability_mode_desc, ars.failover_mode_desc, d.name AS DB_Name, dhs.synchronization_state_desc, dhs.log_send_queue_size, dhs.log_send_rate, dhs.redo_queue_size, dhs.redo_rate, dhs.last_sent_time, dhs.last_received_time, dhs.last_hardened_time, dhs.last_redone_time FROM sys.dm_hadr_availability_group_states ags JOIN sys.availability_groups ag ON ags.group_id = ag.group_id JOIN sys.availability_replicas ar ON ag.group_id = ar.group_id JOIN sys.dm_hadr_availability_replica_states ars ON ar.replica_id = ars.replica_id LEFT JOIN sys.dm_hadr_database_replica_states dhs ON ars.replica_id = dhs.replica_id LEFT JOIN sys.databases d ON dhs.database_id = d.database_id ORDER BY ag.name, ar.replica_server_name, d.name;
重点关注:
synchronization_health_desc(AG级和副本级的健康状态)connected_state_desc(副本是否处于连接状态)log_send_queue_size/redo_queue_size(是否有大量日志积压)synchronization_state_desc(数据库同步状态是否异常)
针对性深度排查查询
如果核心查询没找到问题,试试下面的专项查询:
1. 检查WSFC集群与AG的关联状态
NOT_HEALTHY经常和集群故障或资源问题相关,这个查询能帮你验证AG的集群资源状态:
SELECT ag.name AS AG_Name, ar.replica_server_name, ars.role_desc, ars.operational_state_desc, ars.role_health_desc, ags.primary_replica, ags.primary_recovery_health_desc, ags.secondary_recovery_health_desc FROM sys.dm_hadr_availability_group_states ags JOIN sys.availability_groups ag ON ags.group_id = ag.group_id JOIN sys.availability_replicas ar ON ag.group_id = ar.group_id JOIN sys.dm_hadr_availability_replica_states ars ON ar.replica_id = ars.replica_id;
留意operational_state_desc是否为ONLINE,role_health_desc是否为HEALTHY。
2. 排查副本连接与通信问题
有时候副本看起来正常,但底层通信存在异常:
SELECT ar.replica_server_name, ars.connected_state_desc, ars.last_connect_error_number, ars.last_connect_error_description, ars.last_connect_error_timestamp FROM sys.dm_hadr_availability_replica_states ars JOIN sys.availability_replicas ar ON ars.replica_id = ar.replica_id WHERE ars.connected_state_desc != 'CONNECTED';
如果有连接错误,这里会显示具体的错误码和描述,帮你定位网络或权限问题。
3. 分析日志同步与积压细节
日志同步异常是NOT_HEALTHY的常见原因,这个查询能更细致地查看日志流动情况:
SELECT d.name AS DB_Name, ar.replica_server_name, dhs.synchronization_state_desc, dhs.log_send_queue_size, dhs.log_send_rate, dhs.redo_queue_size, dhs.redo_rate, dhs.filestream_send_rate, dhs.end_of_log_lsn, dhs.last_hardened_lsn, dhs.last_redone_lsn FROM sys.dm_hadr_database_replica_states dhs JOIN sys.databases d ON dhs.database_id = d.database_id JOIN sys.availability_replicas ar ON dhs.replica_id = ar.replica_id WHERE dhs.is_local = 0; -- 查看远程副本的状态
如果log_send_queue_size持续增长,可能是网络带宽不足、副本性能瓶颈或日志生成过快。
4. 检测数据库级别的隐藏异常
有些数据库级的问题不会在副本状态中直接体现:
SELECT d.name AS DB_Name, dhs.synchronization_state_desc, dhs.database_state_desc, dhs.is_suspended, dhs.suspend_reason_desc, dhs.last_error_number, dhs.last_error_description, dhs.last_error_timestamp FROM sys.dm_hadr_database_replica_states dhs JOIN sys.databases d ON dhs.database_id = d.database_id WHERE dhs.database_state_desc != 'ONLINE' OR dhs.is_suspended = 1;
重点看是否有数据库挂起(is_suspended=1)或状态异常,以及对应的错误信息。
5. 查看AG的故障转移与健康事件
SQL Server的扩展事件能记录AG的关键事件,这个查询可以读取近期的AG相关错误:
SELECT event_time, message, severity, error_number FROM sys.fn_xe_file_target_read_file('AlwaysOn_health*.xel', NULL, NULL, NULL) CROSS APPLY (SELECT CAST(event_data AS XML) AS event_xml) AS x WHERE x.event_xml.value('(event/@name)[1]', 'varchar(100)') IN ('error_reported', 'availability_group_lease_expired', 'availability_replica_state_change') ORDER BY event_time DESC;
这个查询会读取AlwaysOn健康扩展事件的日志,帮你找到近期的异常事件。
排查建议
- 先从核心综合查询入手,对比AG级和副本级的
synchronization_health_desc,如果AG是NOT_HEALTHY但个别副本是HEALTHY,重点排查异常副本。 - 检查WSFC集群的节点状态(可以在集群管理器中查看,或用PowerShell命令
Get-ClusterNode),确保所有节点在线。 - 验证AG端点的权限和网络连通性,确保副本之间能通过端点端口通信。
内容的提问来源于stack exchange,提问作者Tony Hinkle
相关产品推荐
相关产品推荐

