Chọn sqlserver.read_only_route_complete
sự kiện mở rộng được đề cập bởi Kin và Remus, đây là một sự kiện Debug hay , nhưng nó không mang nhiều thông tin với nó - chỉ route_port
(ví dụ: 1433) và route_server_name
(ví dụ: sqlserver-0.contoso.com) theo mặc định . Điều này cũng chỉ giúp xác định khi nào kết nối mục đích chỉ đọc thành công. Có một read_only_route_fail
sự kiện nhưng tôi không thể kích hoạt nó, có thể nếu có sự cố với URL định tuyến, nó dường như không kích hoạt khi phiên bản phụ không khả dụng / tắt máy theo như tôi có thể nói.
Tuy nhiên, tôi đã có một số thành công khi tham gia với sqlserver.login
tính năng theo dõi sự kiện và quan hệ nhân quả được kích hoạt, cùng với một số hành động (như sqlserver.username
) để làm cho nó hữu ích.
Các bước để sinh sản
Tạo phiên Sự kiện mở rộng để theo dõi các sự kiện có liên quan, cộng với các hành động hữu ích và theo dõi quan hệ nhân quả:
CREATE EVENT SESSION [xe_watchLoginIntent] ON SERVER
ADD EVENT sqlserver.login
( ACTION ( sqlserver.username ) ),
ADD EVENT sqlserver.read_only_route_complete
( ACTION (
sqlserver.client_app_name,
sqlserver.client_connection_id,
sqlserver.client_hostname,
sqlserver.client_pid,
sqlserver.context_info,
sqlserver.database_id,
sqlserver.database_name,
sqlserver.username
) ),
ADD EVENT sqlserver.read_only_route_fail
( ACTION (
sqlserver.client_app_name,
sqlserver.client_connection_id,
sqlserver.client_hostname,
sqlserver.client_pid,
sqlserver.context_info,
sqlserver.database_id,
sqlserver.database_name,
sqlserver.username
) )
ADD TARGET package0.event_file( SET filename = N'xe_watchLoginIntent' )
WITH (
MAX_MEMORY = 4096 KB,
EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
MAX_DISPATCH_LATENCY = 30 SECONDS,
MAX_EVENT_SIZE = 0 KB,
MEMORY_PARTITION_MODE = NONE,
TRACK_CAUSALITY = ON, --<-- relate events
STARTUP_STATE = ON --<-- ensure sessions starts after failover
)
Chạy phiên XE (xem xét lấy mẫu vì đây là sự kiện Gỡ lỗi) và thu thập một số thông tin đăng nhập:
Lưu ý ở đây sqlserver-0 là thứ cấp dễ đọc của tôi và sqlserver-1 là chính. Ở đây tôi đang sử dụng công -K
tắc sqlcmd
để mô phỏng các thông tin đăng nhập mục đích ứng dụng chỉ đọc và một số thông tin đăng nhập SQL. Sự kiện chỉ đọc kích hoạt đăng nhập mục đích chỉ đọc thành công.
Khi tạm dừng hoặc dừng phiên tôi có thể truy vấn nó và cố gắng liên kết hai sự kiện, ví dụ:
DROP TABLE IF EXISTS #tmp
SELECT IDENTITY( INT, 1, 1 ) rowId, file_offset, CAST( event_data AS XML ) AS event_data
INTO #tmp
FROM sys.fn_xe_file_target_read_file( 'xe_watchLoginIntent*.xel', NULL, NULL, NULL )
ALTER TABLE #tmp ADD PRIMARY KEY ( rowId );
CREATE PRIMARY XML INDEX _pxmlidx_tmp ON #tmp ( event_data );
-- Pair up the login and read_only_route_complete events via xxx
DROP TABLE IF EXISTS #users
SELECT
rowId,
event_data.value('(event/@timestamp)[1]', 'DATETIME2' ) AS [timestamp],
event_data.value('(event/action[@name="username"]/value/text())[1]', 'VARCHAR(100)' ) AS username,
event_data.value('(event/action[@name="attach_activity_id_xfer"]/value/text())[1]', 'VARCHAR(100)' ) AS attach_activity_id_xfer,
event_data.value('(event/action[@name="attach_activity_id"]/value/text())[1]', 'VARCHAR(100)' ) AS attach_activity_id
INTO #users
FROM #tmp l
WHERE l.event_data.exist('event[@name="login"]') = 1
AND l.event_data.exist('(event/action[@name="username"]/value/text())[. = "SqlUserShouldBeReadOnly"]') = 1
DROP TABLE IF EXISTS #readonly
SELECT *,
event_data.value('(event/@timestamp)[1]', 'DATETIME2' ) AS [timestamp],
event_data.value('(event/data[@name="route_port"]/value/text())[1]', 'INT' ) AS route_port,
event_data.value('(event/data[@name="route_server_name"]/value/text())[1]', 'VARCHAR(100)' ) AS route_server_name,
event_data.value('(event/action[@name="username"]/value/text())[1]', 'VARCHAR(100)' ) AS username,
event_data.value('(event/action[@name="client_app_name"]/value/text())[1]', 'VARCHAR(100)' ) AS client_app_name,
event_data.value('(event/action[@name="attach_activity_id_xfer"]/value/text())[1]', 'VARCHAR(100)' ) AS attach_activity_id_xfer,
event_data.value('(event/action[@name="attach_activity_id"]/value/text())[1]', 'VARCHAR(100)' ) AS attach_activity_id
INTO #readonly
FROM #tmp
WHERE event_data.exist('event[@name="read_only_route_complete"]') = 1
SELECT *
FROM #users u
LEFT JOIN #readonly r ON u.attach_activity_id_xfer = r.attach_activity_id_xfer
SELECT u.username, COUNT(*) AS logins, COUNT( DISTINCT r.rowId ) AS records
FROM #users u
LEFT JOIN #readonly r ON u.attach_activity_id_xfer = r.attach_activity_id_xfer
GROUP BY u.username
Truy vấn sẽ hiển thị thông tin đăng nhập có và không có mục đích chỉ đọc ứng dụng:
read_only_route_complete
là một sự kiện Debug vì vậy hãy sử dụng một cách tiết kiệm. Xem xét lấy mẫu chẳng hạn.
- hai sự kiện cùng với quan hệ nhân quả theo dõi cung cấp tiềm năng để thực hiện yêu cầu của bạn - thử nghiệm thêm cần thiết trên giàn khoan đơn giản này
- Tôi đã thông báo nếu tên cơ sở dữ liệu không được chỉ định trong kết nối, mọi thứ dường như không hoạt động
Tôi đã cố gắng để có được pair_matching
mục tiêu để làm việc nhưng hết thời gian. Có một số tiềm năng để phát triển ở đây, đại loại như:
ALTER EVENT SESSION [xe_watchLoginIntent] ON SERVER
ADD TARGET package0.pair_matching (
SET begin_event = N'sqlserver.login',
begin_matching_actions = N'sqlserver.username',
end_event = N'sqlserver.read_only_route_complete',
end_matching_actions = N'sqlserver.username'
)