Skip to content

Commit b10471f

Browse files
0x7FFFFFFFFFFFFFFFrwestMSFT
authored andcommitted
Refresh article and include issue 8495
1 parent ba83c98 commit b10471f

1 file changed

Lines changed: 170 additions & 141 deletions

File tree

docs/database-engine/availability-groups/windows/always-on-ring-buffers.md

Lines changed: 170 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -3,151 +3,180 @@ title: "Ring buffers for health information on availability groups"
33
description: "Obtain certain diagnostics information about Always On availability groups using the SQL Server ring buffers."
44
author: MashaMSFT
55
ms.author: mathoma
6-
ms.date: "06/13/2017"
6+
ms.reviewer: randolphwest
7+
ms.date: 01/30/2023
78
ms.service: sql
89
ms.subservice: availability-groups
910
ms.topic: how-to
1011
ms.custom: seo-lt-2019
1112
---
1213
# Use ring buffers to obtain health information about Always On availability groups
14+
1315
[!INCLUDE [SQL Server](../../../includes/applies-to-version/sqlserver.md)]
14-
Some diagnostic Always On Availability Groups information can be obtained from the SQL Server ring buffers, or the sys.dm_os_ring_buffers dynamic management view (DMV). The ring buffers are created during SQL Server startup, and record alerts within the SQL Server system for internal diagnostics. They are not supported, but you can still extract valuable information from them when troubleshooting issues. These ring buffers provide another source of diagnostics when SQL Server hangs or has crashed.
15-
16-
The following Transact-SQL (T-SQL) query retrieves all event records from the availability groups ring buffers.
17-
18-
```sql
19-
SELECT * FROM sys.dm_os_ring_buffers WHERE ring_buffer_type LIKE '%HADR%'
20-
```
21-
22-
To make the data more manageable, filter the data by date and the ring buffer type. The following query retrieves records from the specified ring buffer that occurred today.
23-
24-
```sql
25-
DECLARE @runtime datetime
26-
SET @runtime = GETDATE()
27-
SELECT CONVERT (varchar(30), @runtime, 121) as data_collection_runtime,
28-
DATEADD (ms, -1 * (inf.ms_ticks - ring.[timestamp]), GETDATE()) AS ring_buffer_record_time,
29-
ring.[timestamp] AS record_timestamp, inf.ms_ticks AS cur_timestamp, ring.*
30-
FROM sys.dm_os_ring_buffers ring
31-
CROSS JOIN sys.dm_os_sys_info inf where ring_buffer_type='<RING_BUFFER_TYPE>'
32-
```
33-
34-
The Record column in each record contains diagnostic data in XML format. The XML data differs between the ring buffer types. For more information on each ring buffer type, see [Availability groups ring buffer types](#BKMK_RingBufferTypes). To make the XML data more readable, you need to customize your T-SQL query to extract the desired XML elements. For example, the following query retrieves all events from the RING_BUFFER_HADRDBMGR_API ring buffer and formats the XML data into separate table columns.
35-
36-
```sql
37-
WITH hadr(ts, type, record) AS
38-
(
39-
SELECT timestamp AS ts, ring_buffer_type AS type, CAST(record AS XML) AS record
40-
FROM sys.dm_os_ring_buffers WHERE ring_buffer_type = 'RING_BUFFER_HADRDBMGR_API'
41-
)
42-
SELECT
43-
ts,
44-
type,
45-
record.value('(./Record/@id)[1]','bigint') AS [Record ID],
46-
record.value('(./Record/@time)[1]','bigint') AS [Time],
47-
record.value('(./Record/HadrDbMgrAPI/dbId)[1]', 'bigint') AS [DBID],
48-
record.value('(/Record/HadrDbMgrAPI/API)[1]', 'varchar(50)') AS [API],
49-
record.value('(/Record/HadrDbMgrAPI/Action)[1]', 'varchar(50)') AS [Action],
50-
record.value('(/Record/HadrDbMgrAPI/role)[1]', 'int') AS [Role],
51-
record.value('(/Record/Stack)[1]', 'varchar(100)') AS [Call Stack]
52-
FROM hadr
53-
ORDER BY record.value('(./Record/@time)[1]','bigint') DESC
54-
GO
55-
```
56-
57-
## <a name="BKMK_RingBufferTypes"></a> Availability groups ring buffer types
58-
There are four availability groups ring buffers in sys.dm_os_ring_buffers. The table below describes the ring buffer types and a sample of the content of the Record column for each ring buffer type.
59-
60-
**RING_BUFFER_HADRDBMGR_API**
61-
62-
Records state transitions that have taken place or are taking place. When looking at the state transitions pay close attention to the objectType values.
63-
64-
```xml
65-
<Record id="11" type="RING_BUFFER_HADRDBMGR_STATE" time="860243">
66-
<HadrDbMgrState>
67-
<objectType>HadrUsers</objectType>
68-
<currentState>HDbMState_Starting</currentState>
69-
<proposedState>HDbMState_Started</proposedState>
70-
<targetState>HDbMState_Started</targetState>
71-
<legalTransition>Y</legalTransition>
72-
<role>1</role>
73-
</HadrDbMgrState>
74-
</Record>
75-
```
76-
77-
**RING_BUFFER_HADRDBMGR_STATE**
78-
79-
Records internal method or function calls made by Always On activity. It can show information such as suspend, resume, or role changes, including both the entry and exit points.
80-
81-
```xml
82-
<Record id="45" type="RING_BUFFER_HADRDBMGR_STATE" time="1723487912">
83-
<HadrDbMgrState>
84-
<dbId>5</dbId>
85-
<objectType>HadrDbMgr</objectType>
86-
<currentState>HDbMState_Starting</currentState>
87-
<proposedState>HDbMState_Started</proposedState>
88-
<targetState>HDbMState_Started</targetState>
89-
<legalTransition>Y</legalTransition>
90-
<role>2</role>
91-
</HadrDbMgrState>
92-
</Record>
93-
```
94-
95-
**RING_BUFFER_HADRDBMGR_COMMIT**
96-
97-
```xml
98-
<Record id="0" type="RING_BUFFER_HADRDBMGR_COMMIT" time="1723475368">
99-
<HadrDbMgrCommitPolicy>
100-
<dbId>5</dbId>
101-
<replicaId>883a18f5-97d5-450f-8f8f-9983a4fa5299</replicaId>
102-
<dbHardenPolicy>KillAll</dbHardenPolicy>
103-
<dbSyncConfig>0x0</dbSyncConfig>
104-
<syncPartnerCount>0</syncPartnerCount>
105-
<minSyncPartnerConfig>0</minSyncPartnerConfig>
106-
<partnerHardenPolicy>KillAll</partnerHardenPolicy>
107-
<partnerSyncConfig>0x0</partnerSyncConfig>
108-
<logBlock>0x0000000000000000</logBlock>
109-
<leaseExpired>Y</leaseExpired>
110-
<partnerChange>N</partnerChange>
111-
<role>2</role>
112-
</HadrDbMgrCommitPolicy>
113-
</Record>
114-
```
115-
116-
**RING_BUFFER_HADR_TRANSPORT_STATE**
117-
118-
```xml
119-
<Record id="3" type="RING_BUFFER_HADR_TRANSPORT_STATE" time="1723485399">
120-
<HadrTransportState>
121-
<agId>08264B79-D10B-412F-B38D-CA07B08E9BD8</agId>
122-
<localArId>883A18F5-97D5-450F-8F8F-9983A4FA5299</localArId>
123-
<targetArId>628D6349-72DD-4D18-A6E1-1272645660BA</targetArId>
124-
<currentState>HadrSession_Configuring</currentState>
125-
<targetState>HadrSession_Connected</targetState>
126-
<legalTransition>Y</legalTransition>
127-
</HadrTransportState>
128-
</Record>
129-
```
130-
131-
## Parse XML data from a ring buffer
132-
You can parse the Record field from the ring buffer you are inspecting by using [value&#40;&#41; Method &#40;xml Data Type&#41;](~/t-sql/xml/value-method-xml-data-type.md) in your query. To use this method, you first need to [CAST](~/t-sql/functions/cast-and-convert-transact-sql.md) the record column in the ring buffer into XML. For example, the query below demonstrates how to parse RING_BUFFER_HADRDBMGR_API into readable format using this method.
133-
134-
```sql
135-
WITH hadr(ts, type, record) AS
136-
(SELECT timestamp AS ts, ring_buffer_type AS type, CAST(record AS XML) AS record
137-
FROM sys.dm_os_ring_buffers
138-
WHERE ring_buffer_type = 'RING_BUFFER_HADRDBMGR_API')
139-
SELECT ts,
140-
type,
141-
record.value('(./Record/@id)[1]','bigint') AS [Record id],
142-
record.value('(./Record/@time)[1]','bigint') AS [Time],
143-
record.value('(./Record/HadrDbMgrAPI/dbId)[1]', 'bigint') AS [dbid],
144-
record.value('(/Record/HadrDbMgrAPI/API)[1]', 'varchar(50)') AS [API],
145-
record.value('(/Record/HadrDbMgrAPI/Action)[1]', 'varchar(50)') AS [Action],
146-
record.value('(/Record/HadrDbMgrAPI/role)[1]', 'int') AS [Role],
147-
record.value('(/Record/Stack)[1]', 'varchar(100)') AS [Call Stack]
148-
FROM hadr
149-
ORDER BY record.value('(./Record/@time)[1]','bigint') DESC
150-
GO
151-
```
152-
153-
16+
17+
Some diagnostic Always On availability group (AG) information can be obtained from the SQL Server ring buffers, or the `sys.dm_os_ring_buffers` dynamic management view (DMV). The ring buffers are created during SQL Server startup, and record alerts within the SQL Server system for internal diagnostics. They aren't supported, but you can still extract valuable information from them when troubleshooting issues. These ring buffers provide another source of diagnostics when SQL Server hangs or has crashed.
18+
19+
The following Transact-SQL (T-SQL) query retrieves all event records from the AG ring buffers.
20+
21+
```sql
22+
SELECT * FROM sys.dm_os_ring_buffers WHERE ring_buffer_type LIKE '%HADR%'
23+
```
24+
25+
To make the data more manageable, filter the data by date and the ring buffer type. The following query retrieves records from the specified ring buffer that occurred today.
26+
27+
```sql
28+
DECLARE @start_of_today DATETIME,
29+
@start_of_tomorrow DATETIME;
30+
31+
SET @start_of_today = CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME);
32+
SET @start_of_tomorrow = DATEADD(DAY, 1, @start_of_today);
33+
34+
DECLARE @runtime DATETIME;
35+
36+
SET @runtime = GETDATE();
37+
38+
SELECT CONVERT(VARCHAR(30), @runtime, 121) AS data_collection_runtime,
39+
DATEADD(ms, - 1 * (inf.ms_ticks - ring.timestamp), GETDATE()) AS ring_buffer_record_time,
40+
ring.timestamp AS record_timestamp,
41+
inf.ms_ticks AS cur_timestamp,
42+
ring.*
43+
FROM sys.dm_os_ring_buffers ring
44+
CROSS JOIN sys.dm_os_sys_info inf
45+
WHERE ring_buffer_type = '<RING_BUFFER_TYPE>'
46+
AND DATEADD(ms, - 1 * (inf.ms_ticks - ring.timestamp), GETDATE()) >= @start_of_today
47+
AND DATEADD(ms, - 1 * (inf.ms_ticks - ring.timestamp), GETDATE()) < @start_of_tomorrow;
48+
GO
49+
```
50+
51+
The `record` column in each record contains diagnostic data in XML format. The XML data differs between the ring buffer types. For more information on each ring buffer type, see [Availability group ring buffer types](#BKMK_RingBufferTypes). To make the XML data more readable, you need to customize your T-SQL query to extract the desired XML elements. For example, the following query retrieves all events from the RING_BUFFER_HADRDBMGR_API ring buffer and formats the XML data into separate table columns.
52+
53+
```sql
54+
WITH hadr (ts, type, record)
55+
AS (
56+
SELECT timestamp AS ts,
57+
ring_buffer_type AS type,
58+
CAST(record AS XML) AS record
59+
FROM sys.dm_os_ring_buffers
60+
WHERE ring_buffer_type = 'RING_BUFFER_HADRDBMGR_API'
61+
)
62+
SELECT ts,
63+
type,
64+
record.value('(./Record/@id)[1]', 'bigint') AS [Record ID],
65+
record.value('(./Record/@time)[1]', 'bigint') AS [Time],
66+
record.value('(./Record/HadrDbMgrAPI/dbId)[1]', 'bigint') AS [DBID],
67+
record.value('(/Record/HadrDbMgrAPI/API)[1]', 'varchar(50)') AS [API],
68+
record.value('(/Record/HadrDbMgrAPI/Action)[1]', 'varchar(50)') AS [Action],
69+
record.value('(/Record/HadrDbMgrAPI/role)[1]', 'int') AS [Role],
70+
record.value('(/Record/Stack)[1]', 'varchar(100)') AS [Call Stack]
71+
FROM hadr
72+
ORDER BY record.value('(./Record/@time)[1]', 'bigint') DESC;
73+
GO
74+
```
75+
76+
## <a id="BKMK_RingBufferTypes"></a> Availability group ring buffer types
77+
78+
There are four AG ring buffers in `sys.dm_os_ring_buffers`. The following section describes the ring buffer types and a sample of the content of the `record` column for each ring buffer type.
79+
80+
#### RING_BUFFER_HADRDBMGR_API
81+
82+
Records state transitions that have taken place or are taking place. When looking at the state transitions, pay close attention to the `objectType` values.
83+
84+
```xml
85+
<Record id="11" type="RING_BUFFER_HADRDBMGR_STATE" time="860243">
86+
<HadrDbMgrState>
87+
<objectType>HadrUsers</objectType>
88+
<currentState>HDbMState_Starting</currentState>
89+
<proposedState>HDbMState_Started</proposedState>
90+
<targetState>HDbMState_Started</targetState>
91+
<legalTransition>Y</legalTransition>
92+
<role>1</role>
93+
</HadrDbMgrState>
94+
</Record>
95+
```
96+
97+
#### RING_BUFFER_HADRDBMGR_STATE
98+
99+
Records internal method or function calls made by AG activity. It can show information such as suspend, resume, or role changes, including both the entry and exit points.
100+
101+
```xml
102+
<Record id="45" type="RING_BUFFER_HADRDBMGR_STATE" time="1723487912">
103+
<HadrDbMgrState>
104+
<dbId>5</dbId>
105+
<objectType>HadrDbMgr</objectType>
106+
<currentState>HDbMState_Starting</currentState>
107+
<proposedState>HDbMState_Started</proposedState>
108+
<targetState>HDbMState_Started</targetState>
109+
<legalTransition>Y</legalTransition>
110+
<role>2</role>
111+
</HadrDbMgrState>
112+
</Record>
113+
```
114+
115+
#### RING_BUFFER_HADRDBMGR_COMMIT
116+
117+
```xml
118+
<Record id="0" type="RING_BUFFER_HADRDBMGR_COMMIT" time="1723475368">
119+
<HadrDbMgrCommitPolicy>
120+
<dbId>5</dbId>
121+
<replicaId>883a18f5-97d5-450f-8f8f-9983a4fa5299</replicaId>
122+
<dbHardenPolicy>KillAll</dbHardenPolicy>
123+
<dbSyncConfig>0x0</dbSyncConfig>
124+
<syncPartnerCount>0</syncPartnerCount>
125+
<minSyncPartnerConfig>0</minSyncPartnerConfig>
126+
<partnerHardenPolicy>KillAll</partnerHardenPolicy>
127+
<partnerSyncConfig>0x0</partnerSyncConfig>
128+
<logBlock>0x0000000000000000</logBlock>
129+
<leaseExpired>Y</leaseExpired>
130+
<partnerChange>N</partnerChange>
131+
<role>2</role>
132+
</HadrDbMgrCommitPolicy>
133+
</Record>
134+
```
135+
136+
#### RING_BUFFER_HADR_TRANSPORT_STATE
137+
138+
```xml
139+
<Record id="3" type="RING_BUFFER_HADR_TRANSPORT_STATE" time="1723485399">
140+
<HadrTransportState>
141+
<agId>08264B79-D10B-412F-B38D-CA07B08E9BD8</agId>
142+
<localArId>883A18F5-97D5-450F-8F8F-9983A4FA5299</localArId>
143+
<targetArId>628D6349-72DD-4D18-A6E1-1272645660BA</targetArId>
144+
<currentState>HadrSession_Configuring</currentState>
145+
<targetState>HadrSession_Connected</targetState>
146+
<legalTransition>Y</legalTransition>
147+
</HadrTransportState>
148+
</Record>
149+
```
150+
151+
## Parse XML data from a ring buffer
152+
153+
You can parse the `Record` field from the ring buffer you are inspecting by using the [value() Method (xml Data Type)](../../../t-sql/xml/value-method-xml-data-type.md) in your query. To use this method, you first need to [CAST](../../../t-sql/functions/cast-and-convert-transact-sql.md) the record column in the ring buffer into XML. For example, the following query demonstrates how to parse `RING_BUFFER_HADRDBMGR_API` into readable format using this method.
154+
155+
```sql
156+
WITH hadr (ts, type, record)
157+
AS (
158+
SELECT timestamp AS ts,
159+
ring_buffer_type AS type,
160+
CAST(record AS XML) AS record
161+
FROM sys.dm_os_ring_buffers
162+
WHERE ring_buffer_type = 'RING_BUFFER_HADRDBMGR_API'
163+
)
164+
SELECT ts,
165+
type,
166+
record.value('(./Record/@id)[1]', 'bigint') AS [Record id],
167+
record.value('(./Record/@time)[1]', 'bigint') AS [Time],
168+
record.value('(./Record/HadrDbMgrAPI/dbId)[1]', 'bigint') AS [dbid],
169+
record.value('(/Record/HadrDbMgrAPI/API)[1]', 'varchar(50)') AS [API],
170+
record.value('(/Record/HadrDbMgrAPI/Action)[1]', 'varchar(50)') AS [Action],
171+
record.value('(/Record/HadrDbMgrAPI/role)[1]', 'int') AS [Role],
172+
record.value('(/Record/Stack)[1]', 'varchar(100)') AS [Call Stack]
173+
FROM hadr
174+
ORDER BY record.value('(./Record/@time)[1]', 'bigint') DESC;
175+
GO
176+
```
177+
178+
## Next steps
179+
180+
- [Configure Extended Events for availability groups](always-on-extended-events.md)
181+
- [Identify waits associated with availability groups](always-on-wait-types.md)
182+
- [Ring Buffer target code for extended events in Azure SQL Database](/azure/azure-sql/database/xevent-code-ring-buffer)

0 commit comments

Comments
 (0)