SQL Server에서 쿼리 완료 및 쿼리 오류 캡처 구성하기
이 기능은 Extended Events (XE)를 사용해 SQL Server 인스턴스에서 쿼리 완료 이벤트와 쿼리 오류 이벤트를 수집해요. 다음에 대한 가시성을 제공해요:
- 파라미터 값이 포함된 SQL 쿼리의 메트릭과 동작
- 실행 중에 발생한 오류와 타임아웃
다양한 데이터베이스 시스템에서의 쿼리 파라미터 캡처에 대한 정보는 파라미터 값이 포함된 쿼리 캡처 구성하기를 참고하세요.
출처: 문서
본문
이 데이터는 다음에 유용해요:
- 성능 분석
- 앱 동작 디버깅
- 예기치 않은 오류 또는 타임아웃 감사
시작하기 전에
이 가이드를 계속하기 전에 SQL Server 인스턴스에 Database Monitoring을 구성해야 해요.
지원되는 데이터베이스: SQL Server
지원되는 배포 유형: 모든 배포 유형.
지원되는 Agent 버전: 7.67.0+
설정 (Setup)
Azure가 아닌 SQL Server
- SQL Server 인스턴스에서 다음 Extended Events (XE) 세션을 만들어요. 이 세션은 인스턴스 내의 어떤 데이터베이스에서든 만들 수 있어요.
datadog_query_completions XE 세션은 RPC 호출, SQL 배치, 저장 프로시저에서 1초가 넘는 장기 실행 SQL 쿼리를 캡처해요.
-- Query completions: RPC, batch, and stored procedure events
IF EXISTS (
SELECT * FROM sys.server_event_sessions WHERE name = 'datadog_query_completions'
)
DROP EVENT SESSION datadog_query_completions ON SERVER;
GO
CREATE EVENT SESSION datadog_query_completions ON SERVER -- datadog requires this exact session name
ADD EVENT sqlserver.rpc_completed ( -- capture remote procedure call completions
ACTION ( -- datadog requires these exact actions for rpc_completed
sqlserver.sql_text,
sqlserver.database_name,
sqlserver.username,
sqlserver.client_app_name,
sqlserver.client_hostname,
sqlserver.session_id,
sqlserver.request_id
)
WHERE (
sql_text <> '' AND
duration > 1000000 -- in microseconds, limit to queries with duration greater than 1 second
)
),
ADD EVENT sqlserver.sql_batch_completed( -- capture batch completions
ACTION ( -- datadog requires these exact actions for sql_batch_completed
sqlserver.sql_text,
sqlserver.database_name,
sqlserver.username,
sqlserver.client_app_name,
sqlserver.client_hostname,
sqlserver.session_id,
sqlserver.request_id
)
WHERE (
sql_text <> '' AND
duration > 1000000 -- in microseconds, limit to queries with duration greater than 1 second
)
),
ADD EVENT sqlserver.module_end( -- capture stored procedure completions
SET collect_statement = (1)
ACTION ( -- datadog requires these exact actions for module_end
sqlserver.sql_text,
sqlserver.database_name,
sqlserver.username,
sqlserver.client_app_name,
sqlserver.client_hostname,
sqlserver.session_id,
sqlserver.request_id
)
WHERE (
sql_text <> '' AND
duration > 1000000 -- in microseconds, limit to queries with duration greater than 1 second
)
)
ADD TARGET package0.ring_buffer -- do not change, datadog is only configured to read from ring buffer at this time
(
SET MAX_MEMORY = 1024
)
WITH (
MAX_MEMORY = 1024 KB, -- do not exceed 1024, values above 1 MB may result in data loss due to SQLServer internals
TRACK_CAUSALITY = ON, -- allows datadog to correlate related events across activity ID
EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
MAX_DISPATCH_LATENCY = 30 SECONDS,
MEMORY_PARTITION_MODE = PER_NODE, -- improves performance on multi-core systems (not supported on RDS)
STARTUP_STATE = ON
);
ALTER EVENT SESSION datadog_query_completions ON SERVER STATE = START;
GO
datadog_query_errors XE 세션은 severity ≥ 11인 SQL 오류와 쿼리 타임아웃(또는 attention 이벤트라고도 함)을 캡처해서, Datadog가 쿼리 실패와 타임아웃을 보고할 수 있게 해요.
-- Errors and timeouts: SQL errors and attention events
IF EXISTS (
SELECT * FROM sys.server_event_sessions WHERE name = 'datadog_query_errors'
)
DROP EVENT SESSION datadog_query_errors ON SERVER;
GO
CREATE EVENT SESSION datadog_query_errors ON SERVER
ADD EVENT sqlserver.error_reported(
ACTION( -- datadog requires these exact actions for error_reported
sqlserver.sql_text,
sqlserver.database_name,
sqlserver.username,
sqlserver.client_app_name,
sqlserver.client_hostname,
sqlserver.session_id,
sqlserver.request_id
)
WHERE severity >= 11
),
ADD EVENT sqlserver.attention(
ACTION( -- datadog requires these exact actions for attention
sqlserver.sql_text,
sqlserver.database_name,
sqlserver.username,
sqlserver.client_app_name,
sqlserver.client_hostname,
sqlserver.session_id,
sqlserver.request_id
)
)
ADD TARGET package0.ring_buffer -- do not change, datadog is only configured to read from ring buffer at this time
(
SET MAX_MEMORY = 1024
)
WITH (
MAX_MEMORY = 1024 KB, -- do not change, setting this larger than 1 MB may result in data loss due to SQLServer internals
EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
MAX_DISPATCH_LATENCY = 30 SECONDS,
MEMORY_PARTITION_MODE = PER_NODE, -- improves performance on multi-core systems (not supported on RDS)
STARTUP_STATE = ON
);
ALTER EVENT SESSION datadog_query_errors ON SERVER STATE = START;
GO
참고: SQL Server용 Amazon RDS를 사용한다면 두 세션 구성 모두에서 MEMORY_PARTITION_MODE = PER_NODE 줄을 제거하세요. 이 옵션은 RDS 인스턴스에서 지원되지 않아요.
Datadog 에이전트 구성에서 sqlserver.d/conf.yaml의 collect_xe를 활성화하세요. 사용 가능한 모든 구성 옵션은 샘플 conf.yaml.example을 참고하세요.
collect_xe:
query_completions:
enabled: true
query_errors:
enabled: true
파라미터 값이 포함된 쿼리 문장을 수집하려면 sqlserver.d/conf.yaml에서 collect_raw_query_statement를 활성화하세요. 파라미터 캡처에 대한 자세한 내용은 파라미터 값이 포함된 쿼리 캡처 구성하기를 참고하세요.
collect_raw_query_statement:
enabled: true
참고: 원시 쿼리 문장에는 민감한 정보(예: 쿼리 텍스트의 비밀번호)나 개인 식별 정보가 포함될 수 있어요. 이 옵션을 활성화하면 Datadog가 쿼리 샘플에 나타나는 원시 쿼리 문장을 수집하고 인제스트할 수 있게 돼요. 이 옵션은 기본적으로 비활성화되어 있어요.
Azure DB
- Azure SQL Server Database에서 다음 Extended Events (XE) 세션을 만들어요:
datadog_query_completions XE 세션은 RPC 호출, SQL 배치, 저장 프로시저에서 1초가 넘는 장기 실행 SQL 쿼리를 캡처해요.
-- Query completions: RPC, batch, and stored procedure events
IF EXISTS (
SELECT * FROM sys.database_event_sessions WHERE name = 'datadog_query_completions'
)
DROP EVENT SESSION datadog_query_completions ON DATABASE;
GO
CREATE EVENT SESSION datadog_query_completions ON DATABASE -- datadog requires this exact session name
ADD EVENT sqlserver.rpc_completed ( -- capture remote procedure call completions
ACTION ( -- datadog requires these exact actions for rpc_completed
sqlserver.sql_text,
sqlserver.database_name,
sqlserver.username,
sqlserver.client_app_name,
sqlserver.client_hostname,
sqlserver.session_id,
sqlserver.request_id
)
WHERE (
sql_text <> '' AND
duration > 1000000 -- in microseconds, limit to queries with duration greater than 1 second
)
),
ADD EVENT sqlserver.sql_batch_completed( -- capture batch completions
ACTION ( -- datadog requires these exact actions for sql_batch_completed
sqlserver.sql_text,
sqlserver.database_name,
sqlserver.username,
sqlserver.client_app_name,
sqlserver.client_hostname,
sqlserver.session_id,
sqlserver.request_id
)
WHERE (
sql_text <> '' AND
duration > 1000000 -- in microseconds, limit to queries with duration greater than 1 second
)
),
ADD EVENT sqlserver.module_end( -- capture stored procedure completions
SET collect_statement = (1)
ACTION ( -- datadog requires these exact actions for module_end
sqlserver.sql_text,
sqlserver.database_name,
sqlserver.username,
sqlserver.client_app_name,
sqlserver.client_hostname,
sqlserver.session_id,
sqlserver.request_id
)
WHERE (
sql_text <> '' AND
duration > 1000000 -- in microseconds, limit to queries with duration greater than 1 second
)
)
ADD TARGET package0.ring_buffer -- do not change, datadog is only configured to read from ring buffer at this time
(
SET MAX_MEMORY = 1024
)
WITH (
MAX_MEMORY = 1024 KB, -- do not exceed 1024, values above 1 MB may result in data loss due to SQLServer internals
TRACK_CAUSALITY = ON, -- allows datadog to correlate related events across activity ID
EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
MAX_DISPATCH_LATENCY = 30 SECONDS,
MEMORY_PARTITION_MODE = PER_NODE, -- improves performance on multi-core systems
STARTUP_STATE = ON
);
ALTER EVENT SESSION datadog_query_completions ON DATABASE STATE = START;
GO
datadog_query_errors XE 세션은 severity ≥ 11인 SQL 오류와 쿼리 타임아웃(또는 attention 이벤트라고도 함)을 캡처해서, Datadog가 쿼리 실패와 타임아웃을 보고할 수 있게 해요.
-- Errors and timeouts: SQL errors and attention events
IF EXISTS (
SELECT * FROM sys.database_event_sessions WHERE name = 'datadog_query_errors'
)
DROP EVENT SESSION datadog_query_errors ON DATABASE;
GO
CREATE EVENT SESSION datadog_query_errors ON DATABASE
ADD EVENT sqlserver.error_reported(
ACTION( -- datadog requires these exact actions for error_reported
sqlserver.sql_text,
sqlserver.database_name,
sqlserver.username,
sqlserver.client_app_name,
sqlserver.client_hostname,
sqlserver.session_id,
sqlserver.request_id
)
WHERE severity >= 11
),
ADD EVENT sqlserver.attention(
ACTION( -- datadog requires these exact actions for attention
sqlserver.sql_text,
sqlserver.database_name,
sqlserver.username,
sqlserver.client_app_name,
sqlserver.client_hostname,
sqlserver.session_id,
sqlserver.request_id
)
)
ADD TARGET package0.ring_buffer -- do not change, datadog is only configured to read from ring buffer at this time
(
SET MAX_MEMORY = 1024
)
WITH (
MAX_MEMORY = 1024 KB, -- do not change, setting this larger than 1 MB may result in data loss due to SQLServer internals
EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
MAX_DISPATCH_LATENCY = 30 SECONDS,
MEMORY_PARTITION_MODE = PER_NODE, -- improves performance on multi-core systems
STARTUP_STATE = ON
);
ALTER EVENT SESSION datadog_query_errors ON DATABASE STATE = START;
GO
Datadog 에이전트 구성에서 sqlserver.d/conf.yaml의 collect_xe를 활성화하세요. 사용 가능한 모든 구성 옵션은 샘플 conf.yaml.example을 참고하세요.
collect_xe:
query_completions:
enabled: true
query_errors:
enabled: true
파라미터 값이 포함된 쿼리 문장을 수집하려면 sqlserver.d/conf.yaml에서 collect_raw_query_statement를 활성화하세요. 파라미터 캡처에 대한 자세한 내용은 파라미터 값이 포함된 쿼리 캡처 구성하기를 참고하세요.
collect_raw_query_statement:
enabled: true
참고: 원시 쿼리 문장과 실행 계획에는 민감한 정보(예: 쿼리 텍스트의 비밀번호)나 개인 식별 정보가 포함될 수 있어요. 이 옵션을 활성화하면 Datadog가 쿼리 샘플이나 실행 계획에 나타나는 원시 쿼리 문장과 실행 계획을 수집하고 인제스트할 수 있게 돼요. 이 옵션은 기본적으로 비활성화되어 있어요.
환경에 맞게 Extended Events 튜닝하기 (선택 사항)
Extended Events 세션을 특정 요구사항에 더 잘 맞게 사용자 정의할 수 있어요:
쿼리 지속 시간 임계값
기본 쿼리 지속 시간 임계값은 duration > 1000000(1초)이에요. 이 값을 조정해 얼마나 많은 쿼리를 캡처할지 제어할 수 있어요:
- 더 많은 쿼리 캡처: 임계값 낮추기(예: 500ms의 경우
duration > 500000) - 더 적은 쿼리 캡처: 임계값 높이기(예: 5초의 경우
duration > 5000000)
경고: 임계값을 너무 낮게 설정하면 과도한 이벤트 수집으로 인해 서버 성능에 영향을 주고, 버퍼 오버플로로 인한 이벤트 손실이 발생하며, Datadog가 수집 주기당 가장 최근 1000개 이벤트만 수집하므로 데이터가 불완전해질 수 있어요.
메모리 할당
- 기본값은
MAX_MEMORY = 1024 KB예요. - 1024 KB를 초과하지 마세요. 더 높은 값은 SQL Server 내부 제한으로 인해 데이터 손실을 일으킬 수 있어요.
- 볼륨이 큰 서버에서는 최대 1024 KB로 유지하는 것이 권장돼요.
- 트래픽이 낮은 서버에서는 512 KB 설정으로 충분할 수 있어요.
이벤트 필터링
이벤트 볼륨을 줄이려면 WHERE 절에 필터를 추가할 수 있어요. 예를 들어:
WHERE (
sql_text <> '' AND
duration > 1000000 AND
-- Add custom filters here
database_name = 'YourImportantDB' AND -- Only track specific databases
username <> 'datadog' -- Exclude Datadog Agent queries or specific users
)
성능 고려 사항
Extended Events는 가볍게 설계되었지만 약간의 오버헤드를 도입할 수 있어요. 성능 문제를 발견하면 다음을 고려하세요:
- 캡처되는 쿼리를 제한하도록 쿼리 지속 시간 임계값을 높이기.
- 이벤트 볼륨을 줄이도록 더 구체적인 필터 추가하기.
- 피크 부하 시간 동안 다음을 실행해 세션 중 하나 또는 둘 다 비활성화하기:
IF EXISTS (
SELECT * FROM sys.server_event_sessions WHERE name = 'datadog_query_completions'
)
DROP EVENT SESSION datadog_query_completions ON SERVER;
GO
IF EXISTS (
SELECT * FROM sys.server_event_sessions WHERE name = 'datadog_query_errors'
)
DROP EVENT SESSION datadog_query_errors ON SERVER;
GO
Azure 특정 고려 사항
Azure SQL Database 환경은 일반적으로 리소스가 더 제한적이에요. 성능 영향을 최소화하려면:
- 낮은 서비스 등급을 사용한다면 더 제한적인 필터를 사용하세요.
- 탄력적 풀(elastic pools)을 사용한다면 모든 데이터베이스에서 성능 영향을 모니터링하세요.